Do not use this function - instead use the built in type(name, bases, dict) constructor This is a function that builds a subclass of some base classes. I wrote it while unaware that type could be used as a constructor.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | import sys as _sys
def subclass(bases, name, suite={}, doc=None):
"""Return a class that inherits from bases
bases is the base class or classes, name is the name of the class, suite is a mapping of
attributes that the subclass should have.
Unfortunately only the metaclass of the first base class will be used at class construction.
Suggestions on how to fix that are welcome.
"""
assert bases, "At least one base class must be supplied"
if not hasattr(bases, '__iter__'):
bases = (bases,)
class cls(bases[0]):
# We can't use the *bases form prior to Python 3. If the later bases do anything clever in
# thier metaclasses, we won't recieve their effects. :-(
locals().update(suite)
# This seems to work reliably in CPython, it's not clear if that's standard
cls.__name__ = name
cls.__bases__ = bases
# Stolen from the NamedTuple implementation
if hasattr(_sys, '_getframe') and _sys.platform != 'cli':
cls.__module__ = _sys._getframe(1).f_globals.get('__name__', '__main__')
if doc:
cls.__doc__ = doc
return cls
|
When reading the implementation of named tuples I thought it was rather a shame that the implementation generated textual source code, and evaled it to yield a new class. Since the obvious means of doing this don't work (type.__new__ can't be called without an already existing subclass), this seems like a fairly clean alternative. It isn't however completely foolproof: Only the metaclass of the first base class will be used.
len(bases)
is not that good - useor
instead.
http://docs.python.org/dev/library/functions.html#type
Jonas: Thanks for that. I've updated the recipe
Christophe: I don't understand what you're pointing out.
Christophe: Oh wait, yes I do! I had no idea type has a three argument form. That's brilliant! Thank you very much!