People used to Java often want Python to have inner classes - that is, classes that can not be instantiated without being associated with an instance of their containing class. There are probably a great many ways to do this. Here's one of them.
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 28 29 30 31 32 33 34
class Outer(object): class Inner(object): def __init__(self, outer): self.outer = outer import new Outer.Inner = new.instancemethod(Outer.Inner, None, Outer) # That's it. Now you cannot create an Inner without an Outer. # For a more self-contained solution using metaclasses: def hasinnerclasses(classname, bases, d): import new, types klass = new.classobj(classname, bases, d) for name,cls in d.items(): if isinstance(cls, (type, types.ClassType)): setattr(klass, name, new.instancemethod(cls, None, klass)) return klass class Outer(object): __metaclass__ = hasinnerclasses class Inner(object): def __init__(self, outer): self.outer = outer >>> out = Outer() >>> inr = out.Inner() # Note that *both* arguments are supplied automatically >>> inr.outer is out True # Trying to cheat doesn't work... >>> cheat = Outer.Inner() #fails >>> cheat = Outer.Inner('foo') #also fails
The biggest drawback to this recipe is that your inner classes end up having the type 'instancemethod', instead of 'type' or 'classobj', so introspection of the outer class would be misleading unless you know what's going on.
Why? Could you explain why a Python programmer would want Java-style inner classes? As far as I remember (admittedly not much) inner classes are used to fake closures, a non-issue in Python. So why would a Python programmer want them?
Actually, I think anonymous classes are what Java uses to fake closures. Named inner classes, as far as I know, are used simply to express a constraint of the object-oriented design - that it makes no sense for an instance of the inner class to exist without an associated instance of the enclosing class.
This recipe is just a way to express and enforce that same constraint in Python.
To be honest, I haven't used this recipe myself - it just occured to me when I noticed in the documentation of new.instancemethod that the first agument can be any callable - it does not specifically have to be a function.
Off the top of my head, I can imagine using it for something like: