module wide metaclass for new style classes

Daniel Nogradi nogradi at gmail.com
Sun Dec 17 04:48:35 EST 2006


> > 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

Thanks a lot, and sorry for the copy-paste error, I had the 'return
type(...)' line but didn't know that this already creates new-style
classes.



More information about the Python-list mailing list