[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