使用字符串设置python对象/变量的名称

时间:2013-02-08 01:04:01

标签: python string function keyword argument-passing

大多数人可能会说这是一个坏主意。我想使用字符串的内容作为变量的名称。我想完成可怕的事情:

s = 'x'
x = 1

变量名x来自字符串s(以某种方式?)。

要回答“为什么?”,请说我有x的全局默认值,我希望选择覆盖函数。但是:

x = 0
def f(**kw):
    print x
f(x=1)

打印0而不是1。如果我可以使用kw.keys()中的字符串重新分配x(或任何其他全局设置变量),那么我会很高兴。

我意识到这适用于在x中重新分配f

x = 0
def f(x=x):
    print x
f(x=1)

但我想在我的命名空间中有多个变量的情况下这样做,我可能在某些时候想要覆盖而不重写我的模块中的每个函数定义。

6 个答案:

答案 0 :(得分:3)

查看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 

另请参阅:How can I assign the value of a variable using eval in python?

经过一些实验,这似乎也有效:

>>> 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

答案 1 :(得分:1)

您应该重新考虑使用global关键字(http://docs.python.org/2.7/reference/simple_stmts.html#the-global-statement

我建议您同时查看Use of "global" keyword in Python

另外,正如promanow所说,使用全局可变对象可能是更好的方法。

但是,请记住,从维护的角度来看,拥有大量可能修改或依赖于变异全局的代码是非常可怕的想法。小心翼翼。

答案 2 :(得分:1)

通过函数参数赋值并不明显,因此不被认为是Pythonic(Python不是C)。请参阅import this

我做平面配置的廉价方式是通过全局部分词典:

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

有效的东西 明显,可读,因此更易于维护。

答案 3 :(得分:1)

  

但我想在我的命名空间中有多个变量的情况下这样做,我可能在某些时候想要覆盖而不重写我的模块中的每个函数定义。

听起来你想要一堂课:

class Foo(object):
    x = 0
    def f(self):
        print self.x

my_foo = Foo()
my_foo.x = 1
my_foo.f()

答案 4 :(得分:0)

我使用以下方法从一个全局数据库中为感兴趣的目标创建动态自定义建模数据库:

DBs = ["Target_1_DB","Target_2_DB","Target_3_DB"]

for db in DBs:
    print(db)    
    exec_str = "Modeling_DB_Base = " + db
    exec(exec_str)
    #s = "Modeling_DB_Base"
    #globals()[s] = db
    print(Modeling_DB_Base.shape)

使用注释掉的globals()会导致错误消息:AttributeError:'str'对象没有属性'shape'

答案 5 :(得分:-2)

您可以使用以下解决方案:

s = 'x'
locals()[s] = 1