__getattribute__ meta class?

grflanagan at gmail.com grflanagan at gmail.com
Tue Feb 26 11:08:39 CET 2008


On Feb 26, 3:43 am, "bambam" <da... at asdf.asdf> wrote:
> I have a class containing a series of classes like this:
>
> class Th(Externaldevice):
>   class _Communicate(commandset2.CommandSet_Communicate):
>     def __getattribute__(self,attrname):
>       attr =
> commandset2.CommandSet_Communicate.__getattribute__(self,attrname)
>       if "__call__" in dir(attr):
>         return functools.partial(Th._wrapper_function, self.parent, attr)
>       else:
>         return attr
>
>   class _System(commandset2.CommandSet_System):
>     def __getattribute__(self,attrname):
>       attr = commandset2.System_Communicate.__getattribute__(self,attrname)
>       if "__call__" in dir(attr):
>         return functools.partial(Th._wrapper_function, self.parent, attr)
>       else:
>        return attr
>
> That is, a a wrapper function is applied to a bunch of methods in a bunch of
> classes.
> The class declarations are simple, but even so, repetitive.
> Can anyone suggest a more compact representation for the class declarations?
> Also, because the parent class name is given explicitly in the class
> declarations, I can't over-ride the _wrapper_function in a child class,
> except by over-riding each of the class declarations. Is there a way to
> reference the _wrapper_function just to the containing class?
>
> Steve

No real idea what you're doing, but surely altering the class at
creation-time, rather than on each attribute call, would be a better
approach?  Here's one idea (sorry if misunderstood your problem):

[code python]
import inspect

def wrapped(func):
    def wrapper(self, arg):
        return func(self, self.parent + ': ' + arg)
    return wrapper

class Meta(type):

    def __new__(cls, name, bases, attrs):
        for key, val in attrs.iteritems():
            if inspect.isfunction(val) and not key.startswith('_'):
                attrs[key] = wrapped(val)
        return super(Meta, cls).__new__(cls, name, bases, attrs)

class Base(object):
    __metaclass__ = Meta
    parent = 'root'

    def foo(self, s):
        return s.upper()

    def bar(self, s):
        return s.lower()

b = Base()

print b.foo('apple')
print b.bar('PEAR')
print
b.parent = 'firstchild'

print b.foo('apple')
print b.bar('PEAR'
[/code]

ROOT: APPLE
root: pear

FIRSTCHILD: APPLE
firstchild: pear

Gerard




More information about the Python-list mailing list