[Python-Dev] classes and cell variables question (original) (raw)

Jeremy Hylton jeremy at alum.mit.edu
Fri Dec 29 20:29:58 CET 2006


On 12/19/06, tomer filiba <tomerfiliba at gmail.com> wrote:

to my understanding of the object model, the code of snippet 1 and snippet 2 should be equivalent. a class is just a "special function" that returns its locals automatically and passes them to the metaclass constructor:

--- snippet 1 --- class foo(object): x = 5 def f(self): print "f", x --- snippet 2 --- def bar(): x = 5 def g(self): print "g", x return locals() barcls = type("barcls", (object,), bar()) but there's one big difference. classes don't create cell variables to hold bound external variables. the "bar" version works, because "x" is a bound cell variable, but the "foo" version fails, as it attempts to access "x" as a global.

Others have explained the rationale for this design choice, and the PEP is a good source for what we were thinking at the time.

I thought it was worth adding that a) class variables can never be access as free variables, as your example foo() shows, and b) you could access a variable bound in a function scope in a method. Example of b):

def spam(): x = 5 # provides the binding for the free variable x in methods of eggs class eggs(object): x = 6 # irrelevant for purposes of resolving the free variable in the method spam def spam(self): # can't have too much spam return x return eggs

spam()().spam() should return 5.

Jeremy

.>>> barcls().g() g 5 .>>> foo().f() f Traceback (most recent call last): File "", line 1, in File "", line 4, in f NameError: global name 'x' is not defined for reference, i attached the code of all four functions below. my question is, how come classes don't create cell variables, like normal functions? was this done on purpose? does it have to do with inheritance? if so, what's wrong with my "bar" version?

[1] # code of class foo ############################################################ # 2 0 LOADNAME 0 (name) # 3 STORENAME 1 (module) # 3 6 LOADCONST 0 (5) # 9 STORENAME 2 (x) # # 4 12 LOADCONST 1 (<code object f at_ _009E5608, file "", line 4>) # 15 MAKEFUNCTION 0 # 18 STORENAME 3 (f) # 21 LOADLOCALS # 22 RETURNVALUE [2] # code of foo.f: ############################################################ # 5 0 LOADCONST 1 ('f') # 3 PRINTITEM # 4 LOADGLOBAL 0 (x) # 7 PRINTITEM # 8 PRINTNEWLINE # 9 LOADCONST 0 (None) # 12 RETURNVALUE [3] # code of bar: ############################################################ # 2 0 LOADCONST 1 (5) # 3 STOREDEREF 0 (x) # # 3 6 LOADCLOSURE 0 (x) # 9 BUILDTUPLE 1 # 12 LOADCONST 2 (<code object g at_ _009F6698, file "", line 3>) # 15 MAKECLOSURE 0 # 18 STOREFAST 0 (g) # # 5 21 LOADGLOBAL 0 (locals) # 24 CALLFUNCTION 0 # 27 RETURNVALUE [4] # code of bar.g: ############################################################ # 4 0 LOADCONST 1 ('g') # 3 PRINTITEM # 4 LOADDEREF 0 (x) # 7 PRINTITEM # 8 PRINTNEWLINE # 9 LOADCONST 0 (None) # 12 RETURNVALUE


Python-Dev mailing list Python-Dev at python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/jeremy%40alum.mit.edu



More information about the Python-Dev mailing list