En Thu, 27 Mar 2008 11:27:42 -0300, dave berk <[EMAIL PROTECTED]> escribió:
> *first:* > Why doesn't this works? > <code> >>>> class C(object): > ... __slots__ = ['foo', 'bar'] > ... class_attr = 'class attribute' > ... >>>> c = C() >>>> c.foo = 'foo' >>>> c.bar = 'bar' >>>> c.bar, c.foo > ('bar', 'foo') >>>> c.__slots__ > ['foo', 'bar'] >>>> c.__slots__.append('eggs') >>>> c.__slots__ > ['foo', 'bar', 'eggs'] >>>> c.eggs = 'eggs' > Traceback (innermost last): > File "<stdin>", line 1, in <module> > AttributeError: 'C' object has no attribute 'eggs' > </code> Because the __slots__ attribute is used when the object is constructed, to reserve space in its structure for those (and only those) attributes. That's the whole point of using __slots__: not creating the generic __dict__ container for all instances to save memory. > *second:* > what happens here? Why can I write to spam using the class object but not > the using the instance? > <code> >>>> class C(object): > ... __slots__ = ['foo', 'bar'] > ... class_attr = 'class attribute' > ... >>>> C.spam = 50 >>>> C.spam > 50 >>>> C.spam = 56 >>>> c = C() >>>> c.spam = 55 > Traceback (innermost last): > File "<stdin>", line 1, in <module> > AttributeError: 'C' object attribute 'spam' is read-only C *instances* are affected by the __slots__ defined in the C *class*, but the C class itself is not. The C class would be affected by a __slots__ defined in its type (the metatype) but since there exist only one C class object, that optimization would be useless. If you were dynamically creating thousands of classes one might consider the point... > *Third:* > <code> > class RevealAccess(object): > """A data descriptor that sets and returns values > normally and prints a message logging their access. > """ > > def __init__(self, initval=None, name='var'): > self.val = initval > self.name = name > > def __get__(self, obj, objtype): > print 'Retrieving', self.name > return self.val > > def __set__(self, obj, val): > print 'Updating' , self.name > self.val = val > class A(object): > def __init__(self): > self.x = RevealAccess(10, 'var "x"') > self.y = 5 > class B(object): > x = RevealAccess(10, 'var "x"') > y = 5 > >>>> a = A() >>>> b = B() >>>> a.x > <__main__.RevealAccess object at 0x00BAC730> >>>> a.x = 55 >>>> b.x > Retrieving var "x" > 10 >>>> b.x = 55 > Updating var "x" >>>> > </code> > Why the descriptor works only when created as a static variable and not > as an instance variable? It's not a "static variable", it's a "class attribute". Classes are objects too, like functions, methods, code... [almost] everything in Python is an object. The descriptor protocol isn't used when retrieving attributes directly from the instance namespace (__dict__), this is a plain dict access. When you say self.x = RevealAccess(...) you are storing the RA instance directly in the instance namespace. Only when retrieving objects from the *class* the descriptor protocol comes into play. -- Gabriel Genellina -- http://mail.python.org/mailman/listinfo/python-list