问题
Most people will probably say this is a bad idea. I want to use the content of a string as the name of a variable. I want to accomplish the dreaded:
s = 'x'
x = 1
where the variable name x
comes (somehow?) from the string s
.
To answer the "why?", say I have a global default value for x
that I want the option of overriding in a function. But:
x = 0
def f(**kw):
print x
f(x=1)
prints 0
not 1
. If I could use the strings in kw.keys() to reassign x
(or any other globally set variables) then I'd be happy.
I realize that this works for reassigning x
in f
:
x = 0
def f(x=x):
print x
f(x=1)
But I want to do this for cases where there are MANY variables in my namespace that I might at some point want to override without rewriting every function definition in my module.
回答1:
Check out exec
>>> print x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
>>> s = 'x'
>>> exec(s + " = 1")
>>> print x
1
See also: How can I assign the value of a variable using eval in python?
After a little experimentation, this also seems to work:
>>> print x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
>>> s = 'x'
>>> globals()[s] = 1
>>> print x
1
回答2:
You should reconsider using the global
keyword (http://docs.python.org/2.7/reference/simple_stmts.html#the-global-statement)
I recommend taking a look at Use of "global" keyword in Python as well.
Also, as promanow suggested, using a global mutable object might be a better approach.
However, keep in mind that having large amounts of code that might modify or depend on a mutating global is very scary idea, from a maintenance perspective. Tread carefully.
回答3:
Assignment via function arguments is not obvious and therefore is not considered Pythonic (Python is not C). See import this
.
The cheap way that I've done flat configuration is through a global partial dict:
In [1]: from functools import partial
In [2]: config = partial(dict)
In [3]: def f(x=None):
...: print x or config.x
...:
In [4]: config.x = 'foo'
In [5]: f()
foo
Something to this effect is obvious, readable and therefore much more maintainable.
回答4:
But I want to do this for cases where there are MANY variables in my namespace that I might at some point want to override without rewriting every function definition in my module.
It sounds like you want a class:
class Foo(object):
x = 0
def f(self):
print self.x
my_foo = Foo()
my_foo.x = 1
my_foo.f()
来源:https://stackoverflow.com/questions/14764088/set-the-name-of-a-python-object-variable-with-a-string