[Python-3000] PEP for Metaclasses in Python 3000
Josiah Carlson
jcarlson at uci.edu
Wed Mar 14 18:51:34 CET 2007
Jack Diederich <jackdied at jackdied.com> wrote:
[snip]
> I don't understand the keyword args other than 'metaclass.'
> If class D inherits from class C does it also get passed the 'Implements'
> keyword? If it does the same effect could be acheived by making a metaclass
> maker function and just using the metaclass keyword.
The keyword arguments to the class ( implements=(I1,I2) ) get passed as
as the **kwargs in meta.__prepare__ (..., **kwargs), as well as the
**kwargs in meta.__new__(..., **kwargs) (though the metaclass= keyword
is removed when calling meta.__new__ ).
> class C(metaclass=Implements(I1, I2)):
> ...
>
> If D doesn't get the 'Implements' keyword then the one-off behavior
> would be easier to put in a class decorator than a metaclass.
> Keywords also strike me as hard to stack. If a class has two keywords
> defining unrelated behaviors the metaclass would have to be a library-like
> thing that understood both of them. Mixing metaclasses from two seperate
> metaclass libraries would be hard - no harder than it currently is but
> keywords will invite more use.
As you say, stacking metaclasses is already hard and this would make
them no more difficult. Combining metaclasses is not a stated purpose
of this particular PEP (at least according to my reading), so I don't
see as how that is in any way a strike against it.
[snip]
> is preferable to this
>
> @seal
> @implements(I1, I2)
> class C():
> ...
It's pre-creation vs. post-creation. As defined, decorators are applied
after the class creation, whereas meta.__prepare__ and meta.__new__
occur before. Note that one of the driving use-cases for
meta.__prepare__, which is called prior to meta.__new__, is to offer
ordered dictionary availability for things like...
class mystruct(structbase):
field1 = int4
field2 = uint8
Or even...
class Contact(row):
_if_not_exists_create = True
firstname = text
middlename = text
lastname = text
The point of offering metaclass=meta is to make it unambiguous what the
metaclass is going to be. As it stands, a user is free to do any of the
following things.
class foo(object):
a = 8
__metaclass__ = True
...
__metaclass__ = fcn(a, __metaclass__)
...
del __metaclass__
__metaclass__ = ...
...
However, because we need the metaclass to be able to call
metaclass.__prepare__, and to discover the metaclass we would have to
emulate the above, we get to a chicken and egg issue. So we pull them
out of the body and define it in the class header.
> or even this
>
> class C(metaclass=meta_library(sealed=True, implements=(I1, I2))):
> ...
If one is allowing metaclass=, I see no point in disallowing other
keywords.
- Josiah
More information about the Python-3000
mailing list