Per instance descriptors ?
Steven Bethard
steven.bethard at gmail.com
Wed Mar 22 15:58:19 EST 2006
bruno at modulix wrote:
> Hi
>
> I'm currently playing with some (possibly weird...) code, and I'd have a
> use for per-instance descriptors, ie (dummy code):
>
> class DummyDescriptor(object):
> def __get__(self, obj, objtype=None):
> if obj is None:
> return self
> return getattr(obj, 'bar', 'no bar')
>
> class MyClass1(object):
> def __init__(self, bar=None):
> if bar is not None:
> self.bar = bar
> self.baaz = DummyDescriptor()
>
> mc1 = MyClass1(bar='back')
> mc1.baaz
> -> <__main__.DummyDescriptor object at 0x2aaaabc6c390>
>
> Which is of course what one would expect... Now I tried the following
> hack^Mworkaround:
>
> class MyClass2(MyClass1):
> def __getattribute__(self, key):
> v = MyClass1.__getattribute__(self, key)
> if hasattr(v, '__get__'):
> return v.__get__(self, self.__class__)
> return v
>
> And it *seems* to work just fine:
>
> mc2 = MyClass2(bar='foo')
> mc2.baaz
> -> 'foo'
>
> Now the question: is there any obvious (or non-obvious) drawback with
> this approach ?
Don't know if this matters, but if you override __getattribute__, you'll
slow down all attribute accesses to this object. If this matters, you
could write something like:
class MyClass(object):
def __init__(self, bar=None):
if bar is not None:
self.bar = bar
def __getattr__(self, name):
if name == 'baaz':
return self.bar
elif name == 'bar':
return 'no bar'
Then you only incur the penalty on the ``baaz`` lookup and the ``bar``
lookup when it's missing -- not on all attribute lookups.
Could you explain again why you don't want baaz to be a class-level
attribute?
STeVe
More information about the Python-list
mailing list