Symbols as parameters?
Steven D'Aprano
steve at REMOVE-THIS-cybersource.com.au
Fri Jan 22 07:55:40 EST 2010
On Fri, 22 Jan 2010 09:29:18 +0100, Alf P. Steinbach wrote:
> But have you tested this within a function or class, which is what the
> use of "locals" implies?
>
> The reason that I ask is that in the documentation of locals() it says
> this:
>
> Note
> The contents of this dictionary should not be modified; changes may
> not affect the values of local variables used by the interpreter.
>
> (There's no such note for 'globals').
>
> I have to admit that I was afraid to post this question since my
> experience in [comp.lang.python] is that when some technical error is
> pointed out by me, then most often the person starts a personal attack
> and credibility attack, injecting all kinds of noise -- actually that
> happened yet again as I was writing this response to you! But, I figure
> one shouldn't give up one humanity just because of one group where that
> happens regularly. I'm sort of counting on you to prove that there are,
> counting myself and one other, and perhaps now you, at least three
> persons here who are happy for technical corrections from me.
I've previously said, and I'll say it again, that you do bring much of
value to this community, tech-wise. Shame that it comes along with such a
thin skin. It's getting so that I often find myself afraid to disagree
with anything you say lest you accuse me of lying again.
> Or, perhaps there's some aspect of locals(), e.g. in the context of
> decorators, that I don't know about and can now learn. :-)
No, you got it spot on. Not to discourage you, but you're at least the
third person who pointed this out in this thread.
One implementation-specific trick is that modifying locals does actually
work inside a class definition (at least in Python 2.5):
>>> class Foo(object):
... x = 1
... print locals()
... locals()['x'] = 2
...
{'x': 1, '__module__': '__main__'}
>>> Foo.x
2
But it doesn't work in functions. That is because the local variables in
CPython functions aren't stored in a dict, for efficiency reasons, so
locals() makes a copy of those variables rather than returning the actual
dict used as a namespace.
This suggests we can cause locals() to malfunction in a class too, by
using slots, since slotted attributes aren't stored in a dictionary.
That's what I would predict, but alas I'm wrong:
>>> class Foo(object):
... __slots__ = 'x'
... x = 1
... print locals()
... locals()['x'] = 2
...
{'x': 1, '__module__': '__main__', '__slots__': 'x'}
>>> Foo.x
2
So I don't understand why this works. Anyone know?
Bottom line is, modifying locals() is not supported as a language
feature. If it works, it's an accident.
(Since Python can't guarantee that modifications to locals() will take, I
wonder whether it would be better to ensure that they *never* take,
rather than sometimes. It would only require locals() to return a copy of
the dict, a shallow copy would probably do.)
--
Steven
More information about the Python-list
mailing list