module wide metaclass for new style classes
Peter Otten
__peter__ at web.de
Sun Dec 17 02:53:30 EST 2006
Daniel Nogradi wrote:
> I used to have the following code to collect all (old style) class
> names defined in the current module to a list called reg:
>
>
> def meta( reg ):
> def _meta( name, bases, dictionary ):
> reg.append( name )
> return _meta
>
> reg = [ ]
> __metaclass__ = meta( reg )
>
> class c1:
> pass
>
> class c2:
> pass
>
> print reg
That code does not create classes. Here's a slightly simplified version:
>> reg = []
>>> def __metaclass__(name, bases, dict):
... reg.append(name)
...
>>> class A: pass
...
>>> reg
['A']
>>> A is None
True # oops!
> This would correctly print [ 'c1', 'c2' ]. Now I would like to switch
> to new style classes but replacing class c1: and class c2: by class
> c1(object): and class c2(object): doesn't work because the metaclass
> associated with object will be called and not mine. Of course if I
> would add __metaclass__ = meta(reg) to all class definitions that
> would work, but how do I do this on the module level?
If present, __metaclass__ serves as a factory for classes without an
explicit base class. For example,
__metaclass__ = type
would turn c1 and c2 into newstyle classes (that inherit from object).
If you want side effects you can wrap the metaclass into a function:
>>> reg = []
>>> def __metaclass__(name, bases, dict):
... reg.append(name)
... return type(name, bases, dict)
...
>>> class A: pass
...
>>> class B: pass
...
>>> reg
['A', 'B']
>>> issubclass(A, object)
True
Peter
More information about the Python-list
mailing list