Are decorators really that different from metaclasses...

Paul Morrow pm_mon at yahoo.com
Thu Aug 26 22:09:42 CEST 2004


Anthony Baxter wrote:
> On Thu, 26 Aug 2004 11:09:28 -0400, Paul Morrow <pm_mon at yahoo.com> wrote:
> 
>>The function does *not* get a new namespace!  Let me stress this point a
>>little further.  We would simply be moving __xxx__ variables *out of*
>>the function's local variable namespace to where they belong, the
>>namespace of the function itself --- /the same namespace that __doc__
>>lives in./
> 
> 
> There _is_ _no_ _such_ _namespace_. __doc__ is an attribute of the
> function object.
> 
> You are proposing to add one. How else is __doc__ = __doc__ + 'extra' to work? 
> 
> Please, please look into how python's namespaces work a bit more. This
> isn't super-complex stuff, and the lovely thing about Python is that
> it's _really_ easy to use introspection to see how these things work.

Yes, it doesn't seem all that complex, although I'm not sure that 
everyone reading this understands them and their subtleties.  The 
following is an excerpt from 
http://docs.python.org/tut/node11.html#SECTION0011200000000000000000

"A namespace is a mapping from names to objects. Most namespaces are 
currently implemented as Python dictionaries, but that's normally not 
noticeable in any way (except for performance), and it may change in the 
future. Examples of namespaces are: the set of built-in names (functions 
such as abs(), and built-in exception names); the global names in a 
module; and the local names in a function invocation. In a sense the set 
of attributes of an object also form a namespace."

When I talk about namespaces, I include all of the above, including the 
sense mentioned in the last line.  So an object's attributes constitute 
a namespace too.  Therefore __doc__, being an attribute of the function 
object, is in the function object's /namespace/.  And note that this is 
*not* a new namespace; it's been there all along.

So now to answer your question about how is __doc__ = __doc__ + 'extra' 
going to work.  It's simple.  But first, we need to define a term.  For 
the sake of this discussion, let's say that 1) specifying a docstring, 
and 2) assigning to a top-level [*] __xxx__ variable inside of a 
function def is making a *'declaration'*.  So in the following function 
def, there are three declarations and one simple assignment.

    def foo():
       """ I am a docstring. """      # declaration
       __doc__ = __doc__ + 'extra'    # declaration
       __author__ = 'Morrow'          # declaration
       pi = 3.14                      # not a declaration

Ok? Now declarations would *not* be like local variable definitions. 
Declarations would be executed in the namespace of the object being 
defined.

     "Declarations encountered during the execution of a def
      statement are executed in the namespace of the function
      or method object being defined."

So in the above example, the three declarations would be executed in the 
namespace of the foo function object.  They would *not* create local 
variables [**].  To help visualize this, the following would be exactly 
equivalent:

    def foo():
       pi = 3.14                      # not a declaration

    foo.__doc__ = """ I am a docstring. """
    foo.__doc__ = foo.__doc__ + 'extra'
    foo.__author__ = 'Morrow'



Paul

* ie. not within a subordinate code block, such as a branch of an if 
statement.

** if the Python system was so modified.




More information about the Python-list mailing list