metaclass & __slots__
Jonathan Hogg
jonathan at onegoodidea.com
Thu Jul 4 17:40:44 EDT 2002
On 4/7/2002 17:47, in article
mailman.1025801286.31332.python-list at python.org, "Alex Martelli"
<aleax at aleax.it> wrote:
> More generally, in your __init__ (whether of a metaclass or
> any other class): call the superclass's __init__ AFTER you have
> performed modifications to the arguments, if you need to change
> the arguments and the superclass's __init__ is going to take
> some action based on them. Metaclasses are no different (in
> this or most other respects) from any other class.
Unfortunately, you can't set or modify __slots__ in the __init__ method of a
metaclass. The damage has already been done by the time you get to the
__init__ method:
>>> class foo( type ):
... def __init__( cls, name, bases, dict ):
... dict['__slots__'] = ['x','y']
... super(foo,cls).__init__( name, bases, dict )
...
>>> class bar:
... __metaclass__ = foo
...
>>> b = bar()
>>> b.x = 10
>>> b.foo = 'heck'
>>> b.__dict__
{'x': 10, 'foo': 'heck'}
>>>
You need to make the change in the __new__ method before the class is
allocated:
>>> class foo( type ):
... def __new__( cls, name, bases, dict ):
... dict['__slots__'] = ['x','y']
... return type.__new__( cls, name, bases, dict )
...
>>> class bar:
... __metaclass__ = foo
...
>>> b = bar()
>>> b.x = 10
>>> b.foo = 'heck'
Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: 'bar' object has no attribute 'foo'
>>> b.__dict__
Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: 'bar' object has no attribute '__dict__'
>>>
See my other post for more on this.
Jonathan
More information about the Python-list
mailing list