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