Python Property Lookup With Custom __setattr__ And __slots__
Solution 1:
The real issue is that I do not understand why there is no conflict between
__slots__
and the property, but there is one between__setattr__
and the property.
Both __slots__
and property
implement attribute lookup by providing a descriptor for the corresponding attribute(s). The presence of __slots__
prevents arbitrary instance attribute creation not by doing anything to __setattr__
, but by preventing creation of a __dict__
. property
and other descriptors don't rely on an instance __dict__
, so they're unaffected.
However, __setattr__
handles all attribute assignment, meaning that descriptor invocation is __setattr__
's responsibility. If your __setattr__
doesn't handle descriptors, descriptors won't be handled, and property
setters won't be invoked.
is there another, more elegant workaround to this problem?
You could explicitly allow only properties:
classA:
...
def__setattr__(self, name, value):
ifnotisinstance(getattr(type(self), name, None), property):
raise AttributeError("Can't assign to attribute " + name)
super().__setattr__(name, value)
or you could explicitly reject assignment to slots, and delegate other attribute assignment to super().__setattr__
:
classA:
...
def__setattr__(self, name, value):
ifisinstance(getattr(type(self), name, None), _SlotDescriptorType):
raise AttributeError("Can't assign to slot " + name)
super().__setattr__(name, value)
# Seems to be the same as types.MemberDescriptorType,# but the docs don't guarantee it.
_SlotDescriptorType = type(A.a)
Post a Comment for "Python Property Lookup With Custom __setattr__ And __slots__"