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.