Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/355.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用字符串设置python对象/变量的名称_Python_String_Function_Keyword_Argument Passing - Fatal编程技术网

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

使用字符串设置python对象/变量的名称,python,string,function,keyword,argument-passing,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(或任何其他全局设置的变量),那么我会很高兴 我意识到这对于在f中重新分配x有效: x = 0 def f(x=x): p

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

s = 'x'
x = 1
其中变量名
x
来自字符串
s

要回答“为什么?”,假设我有一个
x
的全局默认值,我想要在函数中覆盖该值。但是:

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

我意识到这对于在
f
中重新分配
x
有效:

x = 0
def f(x=x):
    print x
f(x=1)
但我希望在命名空间中有许多变量的情况下执行此操作,在某些情况下,我可能希望在不重写模块中的每个函数定义的情况下重写这些变量。

签出

打印x 回溯(最近一次呼叫最后一次): 文件“”,第1行,在 名称错误:未定义名称“x” >>>s='x' >>>执行官(s+“=1”) >>>打印x 1. 另见:

经过一点试验后,这似乎也起到了作用:

>>> 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
打印x 回溯(最近一次呼叫最后一次): 文件“”,第1行,在 名称错误:未定义名称“x” >>>s='x' >>>globals()[s]=1 >>>打印x 1.
您应该重新考虑使用
全局
关键字()

我建议你也去看看

此外,正如promanow所建议的,使用全局可变对象可能是更好的方法


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

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

我进行平面配置的廉价方法是通过全局局部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
这种效果是显而易见的、可读的,因此更易于维护

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

听起来你想要一门课:

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

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

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

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

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

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”

为什么不保留这些“全局”状态变量的dict?几乎没有理由使用eval或exec。在这种情况下,您可以使用getattr或setattr。根据我自己的学习,在这种情况下您将如何使用setattr?您编辑的答案是直接设置全局变量的一种方法。但我通常为真正全局的常量(只读)值保留全局值。如果需要保持状态,请使用类和实例变量。@JesseVogt感谢您对原始问题的直接回答。我很欣赏其他帖子所说的
exec
是一件不好的事情,但知道它处于困境是件好事。我相信你是对的,这是最好的大局答案。我知道我需要学习如何在代码中使用类。考虑到我是在一个有很多不同交互函数的模块中完成这些工作的,那么我想我应该把所有这些相关函数封装在一个类中,以便更好地控制它们共享的参数。我想这将避免或至少有助于解决所有这些函数必须来回传递参数的问题。
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)