[Python-Dev] classes and cell variables question
Guido van Rossum
guido at python.org
Tue Dec 19 23:24:52 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.
>
> .>>> barcls().g()
> g 5
>
> .>>> foo().f()
> f
> Traceback (most recent call last):
> File "<stdin>", line 1, in <module>
> File "<stdin>", 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?
I did this very much on purpose, although I have to think a bit to
remember the reason. I think I didn't want "accidental Java code"
where one would define a class variable and reference it from a method
without prefixing it with self or the class name and it would
accidentally work, but it would be very unpythonic. So I rigged it so
that it wouldn't work.
> [1]
> # code of class foo
> ############################################################
> # 2 0 LOAD_NAME 0 (__name__)
> # 3 STORE_NAME 1 (__module__)
> # 3 6 LOAD_CONST 0 (5)
> # 9 STORE_NAME 2 (x)
> #
> # 4 12 LOAD_CONST 1 (<code object f at
> 009E5608, file "<stdin>", line 4>)
> # 15 MAKE_FUNCTION 0
> # 18 STORE_NAME 3 (f)
> # 21 LOAD_LOCALS
> # 22 RETURN_VALUE
>
> [2]
> # code of foo.f:
> ############################################################
> # 5 0 LOAD_CONST 1 ('f')
> # 3 PRINT_ITEM
> # 4 LOAD_GLOBAL 0 (x)
> # 7 PRINT_ITEM
> # 8 PRINT_NEWLINE
> # 9 LOAD_CONST 0 (None)
> # 12 RETURN_VALUE
>
> [3]
> # code of bar:
> ############################################################
> # 2 0 LOAD_CONST 1 (5)
> # 3 STORE_DEREF 0 (x)
> #
> # 3 6 LOAD_CLOSURE 0 (x)
> # 9 BUILD_TUPLE 1
> # 12 LOAD_CONST 2 (<code object g at
> 009F6698, file "<stdin>", line 3>)
> # 15 MAKE_CLOSURE 0
> # 18 STORE_FAST 0 (g)
> #
> # 5 21 LOAD_GLOBAL 0 (locals)
> # 24 CALL_FUNCTION 0
> # 27 RETURN_VALUE
>
> [4]
> # code of bar.g:
> ############################################################
> # 4 0 LOAD_CONST 1 ('g')
> # 3 PRINT_ITEM
> # 4 LOAD_DEREF 0 (x)
> # 7 PRINT_ITEM
> # 8 PRINT_NEWLINE
> # 9 LOAD_CONST 0 (None)
> # 12 RETURN_VALUE
> _______________________________________________
> 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/guido%40python.org
>
--
--Guido van Rossum (home page: http://www.python.org/~guido/)
More information about the Python-Dev
mailing list