[Python-3000] Metaclasses in Py3K
Talin
talin at acm.org
Sun Dec 17 01:18:13 CET 2006
Josiah Carlson wrote:
> Maybe I'm strange, but I don't like the precreation/double calling
> semantic. It just seems...sloppy? It requires modification of all
> current metaclasses to update to the new metaclass= syntax, just to
> possibly support a single operation, which, according to the discussions
> so far have but a single use-case: taking advantage of operation
> ordering of assignments in the class namespace.
I don't see why any existing metaclasses would need to be re-written -
see below.
> I'd rather not see class dictionary overloading than a metaclass
> double-call semantic.
I see it as more of a "begin / end" kind of operation. One function gets
called to begin the creation of a new class, the second gets called to
finish it. I think of it as compilation - one operation creates a new
template object, and the second one compiles it.
>>> Of course, then we still have __slots__. Will the madness never end?
>> I believe that with this new system, we'll eventually be able to
>> eliminate the need for __slots__. The metaclass can examine the
>> dictionary and create a '__slots__' member based on the decorators or
>> wrappers of the various values within the dict.
>
> At the point of class creation, the only place where attributes of the
> final instance are defined is within __init__, or any other callable
> from __init__. The removal of __slots__ by attempting to introspect on
> the class namespace is either *really hard* or impossible.
>
> Note that __slots__ removal, at least as they currently exist in the
> Python cookbook, basically all rely on introspecting on the argument
> list to __init__. One looks for leading underscores __init__(self, _a,
> _b), others use other semantics. Many of them attempt to generalize on
> problems such as...
>
> class point(object):
> __slots__ = ['x', 'y', 'z']
> def __init__(self, x, y, z):
> self.x = x
> self.y = y
> self.z = z
>
> What makes it not generalizable is that things like the above is for one
> fairly small set of use case that is not covered by any of the autoslots
> implementations.
Slots can be done today, with the existing __metaclass__ syntax:
class Slot:
pass
def slot_holder(name, bases, cdict):
slots = []
newdict = dict(__slots__=slots)
for key, value in cdict.iteritems():
if value is Slot:
slots.append( key )
else:
newdict[ key ] = value
return type(name, bases, newdict)
class X:
__metaclass__ = slot_holder
x = y = z = Slot
def __init__(self, x, y, z):
self.x = x
self.y = y
self.z = z
a = X( 1, 2, 3 )
>>>> 4) Backwards compatibility
>>>>
>>>> It might be possible to retain backwards compatibility if desired. In
>>>> the proposed scheme, the metaclass is invoked twice - once to create the
>>>> dictionary, and once to 'finish' the class. Note that the second step is
>>>> identical to the operation of the current __metaclass__ feature.
>>> Any syntax-based scheme is, by definition, not fully backwards
>>> compatible. The best we can hope for is for new functionality to not
>>> work as intended in previous Pythons, but still be runnable.
>> No, I'm talking about allowing the old __metaclass__ syntax to still
>> continue work in the new versions of Python. It won't have all the
>> functionality of the new syntax, but it will still work as it did before
>> - at least, until we decide to remove it.
>
> That not backwards compatability of new features, it is forwards
> compatability of old features.
Huh? I don't understand. In my lexicon, the term "backwards
compatibility" generally means that existing code will continue to run
on a new version of the interpreter and/or standard libraries.
As I see it, any class that uses the "__metaclass__ = foo" syntax would
continue to work exactly like it does today - assuming we want it to.
I'm basically saying that the new proposal and the existing system do
not interfere with each other, and share some common implementation
elements, that's all.
I don't see why you feel that all existing metaclasses would need to be
re-written.
-- Talin
More information about the Python-3000
mailing list