On inner classes

mcherm mcherm at destiny.com
Mon Feb 25 23:36:02 CET 2002


bjorn writes:
> You can't. Think about it. Your inner_class is at class scope in
> outer_class. What you're after is a value of an *instance* of
> outer_class, however you have no handle to such an instance from within
> inner_class, ergo you can't get to it.

Maybe I can make this a little clearer. Your use of the term "inner 
class" suggests that you might be coming from a Java background. In 
java, there are things called inner classes, and the way that they work 
is that each instance of the inner class is "magically" connected to an
instance of the outer class.

That's not what happens when you declare one class inside of another in 
Python -- in Python the "inner" class is just another class, and its 
instances are not "magically" bound to instances of the outer class. 
It's as if (in Python language) they were declared to be STATIC inner 
classes.

Most of the time, this is the behavior that you want -- inner classes in 
Java were invented to solve problems that are really easy to handle in 
Python because of the existance of bound methods. (I can explain what 
that meant if you like.) But as you might expect, if you actually DO 
want the java-like behavior, Python allows it, you just have to be 
explicit and explain what you mean.

Here's some code illustrating what I mean:

----------------<sample>--------------------
Python 2.2c1 (#27, Dec 14 2001, 13:15:16) [MSC 32 bit (Intel)] on win32
Type "copyright", "credits" or "license" for more information.
IDLE 0.8 -- press F1 for help
 >>> class Outer:
	def makeAnInner(self):

		class Inner:
			def __init__(self, myOuter):
				self.myOuter = myOuter
			def innerMethod(self):
				print "I'm an inner, my outer is %s" % self.myOuter
				self.myOuter.outerMethod()
		anInner = Inner(self)
		anInner.innerMethod()
	def outerMethod(self):
		print "This is an outer method."

		
 >>> anOuter = Outer()
 >>> anOuter.makeAnInner()
I'm an inner, my outer is <__main__.Outer instance at 0x00954E90>
This is an outer method.
----------------</sample>--------------------

There are only two things you have to do differently here than in 
Java... you have to declare the __init__() method of Inner to take a 
myOuter parameter and store it, and you have to explicitly pass the 
outer when you create it in the line "anInner = Inner(self)". By 
requiring you to explicitly create this outer-inner relationship when 
you want it, Python adds the ability to NOT have the relationship when 
you DON'T need it.

-- Michael Chermside





More information about the Python-list mailing list