I
Ian Sparks
Hi all,
I wanted to do some magick to classes so that any method.__name__.startswith('list') would be expected to return a list and would magically wrap the elements of that list with an ItemWrapper() instance.
For instance, this might be useful for automatically wrapping the rows of a cursor result set from a database with the excellent dtuple. Besides, it's evil, and sometimes evil is good.
This is what I came up with using Python 2.3 (no @ available). Is there a better way?
class ItemWrapper:
"""A class that wraps an item in a list"""
def __init__(self,item):
self.item = item
def val(self):
"""Example wrapped method"""
return self.item
class ListWrapper:
"""
Wraps the elements of a functions return list with
ItemWrapper() instances
"""
def __init__(self,f):
self.f = f
def __call__(self,*args,**kwds):
vals = self.f(self.f,*args,**kwds)
return [ItemWrapper(x) for x in vals]
class MyMeta(type):
"""
Metaclass that will wrap methods who's names
start with 'list' with ListWrappers
"""
def __new__(cls, name, bases, dct):
for key,item in dct.items():
if key.startswith('list'):
import types
if type(item) == types.FunctionType:
dct[key] = ListWrapper(dct[key])
return type.__new__(cls, name, bases, dct)
class ParentTest:
"""
Parent class to inherit from, so folks know that they're
declaring a class with magick
"""
__metaclass__ = MyMeta
class Test(ParentTest):
"""
A class who's listXXX methods return lists of ItemWrappers()
instead of what is expected. BWWWWAHAHAHAHAH!
"""
def list1(self):
return [1,2,3,4]
if __name__ == '__main__':
t = Test()
vals = t.list1()
for x in vals:
print x,x.val()
I wanted to do some magick to classes so that any method.__name__.startswith('list') would be expected to return a list and would magically wrap the elements of that list with an ItemWrapper() instance.
For instance, this might be useful for automatically wrapping the rows of a cursor result set from a database with the excellent dtuple. Besides, it's evil, and sometimes evil is good.
This is what I came up with using Python 2.3 (no @ available). Is there a better way?
class ItemWrapper:
"""A class that wraps an item in a list"""
def __init__(self,item):
self.item = item
def val(self):
"""Example wrapped method"""
return self.item
class ListWrapper:
"""
Wraps the elements of a functions return list with
ItemWrapper() instances
"""
def __init__(self,f):
self.f = f
def __call__(self,*args,**kwds):
vals = self.f(self.f,*args,**kwds)
return [ItemWrapper(x) for x in vals]
class MyMeta(type):
"""
Metaclass that will wrap methods who's names
start with 'list' with ListWrappers
"""
def __new__(cls, name, bases, dct):
for key,item in dct.items():
if key.startswith('list'):
import types
if type(item) == types.FunctionType:
dct[key] = ListWrapper(dct[key])
return type.__new__(cls, name, bases, dct)
class ParentTest:
"""
Parent class to inherit from, so folks know that they're
declaring a class with magick
"""
__metaclass__ = MyMeta
class Test(ParentTest):
"""
A class who's listXXX methods return lists of ItemWrappers()
instead of what is expected. BWWWWAHAHAHAHAH!
"""
def list1(self):
return [1,2,3,4]
if __name__ == '__main__':
t = Test()
vals = t.list1()
for x in vals:
print x,x.val()