Are decorators really that different from metaclasses...

Paul Morrow pm_mon at
Tue Aug 31 14:47:38 CEST 2004

The big impact of this proposal is that __xxx__ variables defined 
immediately following the docstring (if present) would cease to become 
local variables.  This of course has the possiblity of breaking existing 
code.  But I don't believe that developers routinely use such names for 
local variables, so I don't believe that there will actually be much 
broken code should this change be implemented.

Jeff Epler wrote:
> In your proposed model, what does the following code do?
>     def f():
>         __var__ = 3
>         return __var__
>     f.__var__ += 1
>     print f()

Only assignments to __xxx__ variables at the very start of a function 
def would have this special semantics.  So your return statement would 
be referencing a name (__var__) that doesn't exist in the function's 
local variable namespace.

Easier to accept if we use a more likely variable name for the magic 

     def f():
         __version__ = 3
         return __version__
     f.__version__ += 1
     print f()

> What about any of the following:
>     def g():
>         if True:
>             __var__ = 4
>     print g.__var__

__var__ = 4      # creates a local variable because
                  # the assignment isn't at top
                  # of function def.  But probably
                  # should generate a warning for
                  # giving a magic name to a local
                  # variable.

>     x = 3
>     def h(x):
>         __var__ = x*x
>         return x*x
>     print h(2), h.__var__

In __var__ = x*x, x is not in the function's namespace (it's a local 
variable), so x is undefined.  Easier to visualize if we make it 
__version__ = x*x

Same basic idea for your other examples.

>     def p():
>         import os as __os__

__os__ would be a local variable (since this is not a simple assignment, 
i.e. using an equal sign).  __os__ is not a good name for a local 
variable, so interpretor should probably generate a warning.

>     def q(): # BUG x doesn't get the proper metaclass in 2.3!
>         class __metaclass__(type): pass
>         class x: pass
>         # assert x's metaclass is __metaclass__

This would do whatever it does now.


More information about the Python-list mailing list