On 12/19/06, tomer filiba <[EMAIL PROTECTED]> 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@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/) _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com