In trying to support user requests for C++-like behavior of wrapped static data members, I noticed the following little assymetry: >>> #define a property class ... class Prop(object): ... def __get__(self, obj, type=None): ... print '__get__', (self, obj, type) ... return 'value' ... ... def __set__(self, obj, type=None): ... print '__set__', (self, obj, type) ... ... def __delete__(self, obj, type=None): ... print '__delete__', (self, obj, type) ... >>> # use it in a class Y ... class Y(object): ... x = Prop() ... >>> a = Y() >>> a.x # all accesses to a.x are intercepted __get__ (<__main__.Prop object at 0x00877BC8>, <__main__.Y object at 0x00878108>, <class '__main__.Y'>) 'value' >>> a.x = 42 __set__ (<__main__.Prop object at 0x00877BC8>, <__main__.Y object at 0x00878108>, 42) >>> Y.x # Prop intercepts reads of the class attribute __get__ (<__main__.Prop object at 0x00877BC8>, None, <class '__main__.Y'>) 'value' >>> Y.x = 1 # But not assignments >>> Y.x 1 >>> class mc(object.__class__): # to intercept Y.x assignment ... x = Prop() # I have to define this ... >>> class Y(object): ... __metaclass__ = mc ... >>> Y.x # now all accesses to Y.x are intercepted __get__ (<__main__.Prop object at 0x00876AB8>, <class '__main__.Y'>, <class '__main__.mc'>) 'value' >>> Y.x = 1 __set__ (<__main__.Prop object at 0x00876AB8>, <class '__main__.Y'>, 1) >>> a = Y() # But not accesses to a.x >>> a.x Traceback (most recent call last): File "<stdin>", line 1, in ? AttributeError: 'Y' object has no attribute 'x' >>> As you can see, the only way to intercept assignment to Y.x is to stick a property Y's class, i.e. the metaclass (or to modify __setattr__ in the metaclass, but it amounts to the same thing). In C++, a mutable static data member can be modified via the class Y::x = 1; or an instance of the class a.x = 1; I notice that Python supports this sort of dual access for reading attributes and calling static functions, but getting that behavior for mutable attributes seems unreasonably difficult: I need a property in the metaclass *and* in the class. 1. To throw out a straw-man suggestion, what about adding an additional protocol __set2__ which, if found, will be called instead of __set__ both for reading _and_ writing attributes on the class? 2. What are the optional type=None arguments for? It seems as though only the middle argument (obj) is ever None. I just copied this protocol out of descrintro.html 3. Is there documentation for __delete__ anywhere? -- Dave Abrahams Boost Consulting www.boost-consulting.com
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4