nesting class definitions?

Thomas Wouters thomas at xs4all.net
Fri Jan 28 12:20:32 EST 2000


On Thu, Jan 27, 2000 at 03:55:51PM +0100, Gerrit Holl wrote:

> I do see the point in nesting function definitions, namely as an alternative
> on places where one could use lambda. But what's the point in nesting
> class definitions? I know it's possible, but I've never seen it used.

> There aren't functions in the default library that take a class as
> argument, are there?

Nesting doesn't really *do* anything in python, except bind the class to a
different namespace. And there is no difference between classes, modules,
functions, lists, dictionaries or any of the other objects. For instance:

class Viking:
	class Spam:
		pass

is effectively equivalent to:

class private_Spam:
	pass

class Viking:
	Spam = private_Spam

Because python only has 2 'active' namespaces, local and global, it does not
matter where a class or function is created, other than in which module. It
will only ever 'see' it's own namespace, which is private to itself, and the
module toplevel namespace.

And dont forget that you can pass classes and functions around just like any
other object:

>>> class Viking:
...         class Spam:
...                 def __init__(self, counter):
...                         self.counter = counter
...                 def __call__(self):
...                         print "spam "*self.counter
...         def __init__(self):
...                 self.counter = 0
...         def __call__(self):
...                 self.counter = self.counter + 1
...                 return self.Spam(self.counter)
...
>>> foo = Viking()
>>> foo()
<__main__.Spam instance at 80d4dd8>
>>> foo()
<__main__.Spam instance at 80d4ac0>
>>> foo()()
spam spam spam 
>>> foo()()
spam spam spam spam 

>>> class Spam:
...     def __init__(self, counter):
...             pass
...     def __call__(self):
...             print "I'm NOT the messiah!"
...
>>> Viking.Spam = Spam
>>> foo()()
I'm NOT the messiah!

Python makes no distinction between the original Spam class and the new one.
All existing instances of the old Spam keep their parent, of course, but any
new instances generated by Viking's __call__ method will use the new one.
The 'toplevel' Spam also doesn't overwrite the Viking.Spam until the
actual assignment. (The internal 'name' for Viking.Spam, __main__.Spam,
notwithstanding.)

So, in a sense, there is no actual nesting. The definition of a class or a
function does 2 things: creating the actual class or function object, and
assigning it to a name in the local namespace. In what namespace you execute
the 'class' or 'def' statement only affects where the name is bound, not how
it's treated.

And why should we use nesting then, if it's all namespace-magic ? Well,
because it's namespace magic, and python is cool like that. Perhaps you do
not want to pollute the main namespace with auxillary functions and classes,
or perhaps you want to have your auxillary class or function 'close', to
speed up accesses to them. Or perhaps it's just more obvious, easier to
read.

(There are, by the way, functions that take a class as argument... think
'isinstance()'. But wether or not class definitions are nested does not in
any way affect it. You can call isinstance() on a locally defined class just
as you can do it on a globally defined class, or qualified with a namespace
(Viking.Spam, myModule.Spam, etc)

To miss-quote Tim,
Namespaces-are-one-honking-great-idea----let's-do-more-of-those!-ly y'rs
-- 
Thomas Wouters <thomas at xs4all.net>

Hi! I'm a .signature virus! copy me into your .signature file to help me spread!




More information about the Python-list mailing list