[Python-Dev] metaclass insanity

Kevin Jacobs jacobs@penguin.theopalgroup.com
2002年10月30日 09:15:52 -0500 (EST)


On 30 Oct 2002, Michael Hudson wrote:
> For moderately nefarious reasons[1] I've being trying to write a
> metaclass whose instances have writable __bases__. This in itself
> isn't so hard, but having assigments to __bases__ "do the right thing"
> has eluded me, basically because I can't seem to affect the mro.

The mro is an internal data structure of new-style classes, so redefining
mro() doesn't change the values used. Here is my (non-working version) that
attempts to re-assign the class of an object, although it fails on a layout
violation with Python 2.2.2.
def base_getter(cls):
 return cls.__my_bases__
def base_setter(cls,bases):
 if not bases:
 bases = (object,)
 metaclass = getattr(cls, '__metaclass__', type)
 new_cls = metaclass(cls.__name__, bases, dict(cls.__dict__))
 cls.__class__ = new_cls
class MetaBase(type):
 __bases__ = property(base_getter,base_setter)
 def __new__(cls, name, bases, ns):
 ns['__my_bases__'] = tuple(bases)
 return super(MetaBase, cls).__new__(cls, name, bases, ns)
class Foo(object):
 __metaclass__ = MetaBase
class Baz(object): pass
Foo.__bases__ = Foo.__bases__ + (Baz,)
Which results in:
 TypeError: __class__ assignment: 'Foo' object layout differs from 'MetaBase'
I haven't looked into why this is being flagged as a layout error, though
my first instinct is to say that the check is too conservative in this case.
I'll think about it more and dig into the code.
-Kevin
--
Kevin Jacobs
The OPAL Group - Enterprise Systems Architect
Voice: (216) 986-0710 x 19 E-mail: jacobs@theopalgroup.com
Fax: (216) 986-0714 WWW: http://www.theopalgroup.com

AltStyle によって変換されたページ (->オリジナル) /