tag:blogger.com,1999:blog-4637631607249418081.post4622029421918408004..comments2023-10-07T00:29:30.516-07:00Comments on The Other Kelly Yancey: Python: Typed attributes using descriptorsKelly Yanceyhttp://www.blogger.com/profile/08648597728708472240noreply@blogger.comBlogger6125tag:blogger.com,1999:blog-4637631607249418081.post-64815764162127437392007-08-05T18:55:00.000-07:002007-08-05T18:55:00.000-07:00To the anonmyous poster suggesting the enthought t...To the anonmyous poster suggesting the enthought traits package: thanks for the pointer. Interestingly, I don't see were the traits package allows composition of descriptors either (in fact, it looks like most of its magic happens in metaclasses). In any event, I see that descriptors take flags like "allow_none" in lieu of proper composition.Kelly Yanceyhttps://www.blogger.com/profile/08648597728708472240noreply@blogger.comtag:blogger.com,1999:blog-4637631607249418081.post-73321663545660785032007-08-05T18:52:00.000-07:002007-08-05T18:52:00.000-07:00Luke: Your Unsigned type doesn't cut it, you can s...Luke: Your Unsigned type doesn't cut it, you can still assign signed values to it after initialization. The only way to prevent that (that I am aware of) is to use descriptors since you could override the __set__ method to prevent assignment of signed values. But then that gets us back to the original question: is it possible to compose descriptors? I have yet to see evidence that you can.Kelly Yanceyhttps://www.blogger.com/profile/08648597728708472240noreply@blogger.comtag:blogger.com,1999:blog-4637631607249418081.post-21347995289293304372007-08-03T13:12:00.000-07:002007-08-03T13:12:00.000-07:00Python's descriptors are really great; they change...Python's descriptors are really great; they change the way you think about classes.<BR/><BR/>A more full-on extension of this concept can be found at <BR/><BR/>http://code.enthought.com/traits/Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-4637631607249418081.post-29439243846978955202007-08-03T08:41:00.000-07:002007-08-03T08:41:00.000-07:00It's a little awkward to figure out where you shou...It's a little awkward to figure out where you should store attributes. I've given up in a lot of cases and just passed the attribute name in, like "attr = SomeDescriptor('attr')". It makes the objects pickleable too, and other positive things.<BR/><BR/>You might find these descriptors interesting (there's also some in ohm.persist): http://svn.pythonpaste.org/Paste/OHM/trunk/ohm/descriptors.pyIan Bickinghttps://www.blogger.com/profile/10921115783730718101noreply@blogger.comtag:blogger.com,1999:blog-4637631607249418081.post-33554249362118730592007-08-03T06:58:00.000-07:002007-08-03T06:58:00.000-07:00Regarding composition:Does 'NotNone' or 'Unsigned'...Regarding composition:<BR/><BR/>Does 'NotNone' or 'Unsigned' take a type and return a descriptor, or do they take descriptors and return descriptors? This is the fundamental confusion.<BR/><BR/>If you say that only 'TypedAttr' takes a type and returns a descriptor, then you are in luck. Make 'Unsigned' be a class factory that takes a type and returns a type with restrictions enforced in the constructor (or something). You can subclass builtin number types using the following.<BR/><BR/><BR/>def Unsigned(t):<BR/>__"""Takes a type an returns a subclass that forces it's value to be postive"""<BR/><BR/>__class _Unsigned(t):<BR/>____def __init__(self, x):<BR/>______if x < 0:<BR/>________raise Exception("Must be positive")<BR/>__return _UnsignedLuke Planthttps://www.blogger.com/profile/10988266347497131512noreply@blogger.comtag:blogger.com,1999:blog-4637631607249418081.post-57127640795573785192007-08-03T05:32:00.000-07:002007-08-03T05:32:00.000-07:00A descriptor shouldn't store data itself: values a...A descriptor shouldn't store data itself: values are not cleaned up when an instance of a class that has such a descriptor is deleted. This could be fixed by changing the dictionary to a WeakKeyDictionary, provided that the classes allow weak references. Also your classes may be unhashable.<BR/><BR/>I also did such descriptors once and I generated slot names with a counter and used getattr(), setattr() and delattr() on the instance. This way you don't have the problems described above and even see the values when inspecting the objects with vars(). Another upside of using counters is that you know in which order the descriptors are declared.Anonymousnoreply@blogger.com