On 9/20/2010 5:51 AM, Bruno Desthuilliers wrote:
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...
In the 3.x doc, this is now the recommended method. The self.__dict__
idiom predates new-style classes, object, and super.
To the OP. It is possible that you have seem bad (useless, redundant)
uses as well as uses that were necessary with old-style user classes.
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}
--
Terry Jan Reedy
--
http://mail.python.org/mailman/listinfo/python-list