Steven D'Aprano a écrit :
On Mon, 20 Sep 2010 09:27:25 +0200, Bruno Desthuilliers wrote:
If the class has a .__setattr__ method, the first bypasses that method,
It also bypasses object.__setattribute__ and - as a consequence - any
binding descriptor by the same name as the attribute being set.
__setattribute__ ?
object.__setattribute__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: type object 'object' has no attribute '__setattribute__'
Duh...
Brain fart, sorry, shouldn't post before I get my dose of coffee :(
Let's do it again:
Terry Reedy a écrit :
> If the class has a .__setattr__ method, the first bypasses that
> method,
All new-style classes have a __setattr__ method - whether inherited from
object or overridden. object.__setattr__ implements the support for
binding descriptors, so bypassing it will also bypass all binding
descriptors.
The right way to avoid infinite recursion when overriding __setattr__
is to call on the superclass __setattr__, unless of course you *really*
know what you're doing...
class BarDescriptor(object):
def __init__(self):
self.val = None
def __set__(self, instance, value):
print "stores value elsewhere and trigger some required behaviour"
self.val = value * 2
def __get__(self, instance, cls=None):
if instance is None:
return self
print "retrieve value from elsewhere and trigger some required
behaviour"
return self.val
# well behaved
class Foo(object):
bar = BarDescriptor()
def __init__(self):
self.bar = 42
def __setattr__(self, name, value):
print "override __setattr_ for some reason"
super(Foo, self).__setattr__(name, value)
# ugly mess
class Baaz(Foo):
bar = BarDescriptor()
def __init__(self):
self.__dict__['bar'] = 42
def __setattr__(self, name, value):
print "override __setattr_ for some reason"
self.__dict__[name] == value
>>> f = Foo()
override __setattr_ for some reason
stores value elsewhere and trigger some required behaviour
>>> f.bar
retrieve value from elsewhere and trigger some required behaviour
84
>>> f.__dict__
{}
>>> f.bar = 33
override __setattr_ for some reason
stores value elsewhere and trigger some required behaviour
>>> f.bar
retrieve value from elsewhere and trigger some required behaviour
66
>>> f.__dict__
{}
>>> b = Baaz()
>>> b.__dict__
{'bar': 42}
>>> b.bar
retrieve value from elsewhere and trigger some required behaviour
>>> b.bar = 33
override __setattr_ for some reason
>>> b.bar
retrieve value from elsewhere and trigger some required behaviour
>>> b.__dict__
{'bar': 42}
>>>
--
http://mail.python.org/mailman/listinfo/python-list