Are decorators really that different from metaclasses...

Anthony Baxter anthonybaxter at gmail.com
Fri Aug 27 11:34:40 EDT 2004


[I was going to leave this thread alone now, but I need to correct
another piece of misinformation before I go, in case the 3 or 4 people
who've stayed with this thread get the wrong idea <wink>]

On Thu, 26 Aug 2004 16:09:42 -0400, Paul Morrow <pm_mon at yahoo.com> wrote:
> 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.

"In a sense" is the bit you're missing here. You can't just hand-wave
and say that it's a namespace. It's *not* a namespace. If it was, you
could do any of these:

>>> def foo():
...   "a docstring"
...
>>>
>>> eval('__doc__', foo)
Traceback (most recent call last):
 File "<stdin>", line 1, in ?
TypeError: globals must be a dict
>>> eval('__doc__', globals(), foo)
Traceback (most recent call last):
 File "<stdin>", line 1, in ?
TypeError: locals must be a mapping
>>> exec '__doc__ = __doc__ + "extra"' in foo
Traceback (most recent call last):
 File "<stdin>", line 1, in ?
TypeError: exec: arg 2 must be a dictionary or None

Note that if I use a real dict, I get the correct result:
>>> d=dict(__doc__ = 'docstring')
>>> exec '__doc__ = __doc__ + "extra"' in d
>>> d['__doc__']
'docstringextra'

If and when you can make the above work, then come back and re-visit
your idea. Better yet, play around a bit and figure out _why_ they
don't work - it's a good learning exercise.

Anthony



More information about the Python-list mailing list