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__"