Python 如何在当前模块上调用setattr()?
我应该将什么作为第一个参数“Python 如何在当前模块上调用setattr()?,python,module,global-variables,getattr,setattr,Python,Module,Global Variables,Getattr,Setattr,我应该将什么作为第一个参数“object”传递给函数setattr(object,name,value),以设置当前模块上的变量 例如: setattr(object, "SOME_CONSTANT", 42); 具有与以下相同的效果: SOME_CONSTANT = 42 在包含这些行的模块内(使用正确的对象) 我将在模块级别动态生成多个值,由于我无法在模块级别定义\uu getattr\uuu,因此这是我的回退 import sys thismodule = sys.modules[_
object
”传递给函数setattr(object,name,value)
,以设置当前模块上的变量
例如:
setattr(object, "SOME_CONSTANT", 42);
具有与以下相同的效果:
SOME_CONSTANT = 42
在包含这些行的模块内(使用正确的对象
)
我将在模块级别动态生成多个值,由于我无法在模块级别定义\uu getattr\uuu
,因此这是我的回退
import sys
thismodule = sys.modules[__name__]
setattr(thismodule, name, value)
或者,不使用setattr
(这会打断问题的字母,但满足相同的实际目的;-):
注意:在模块范围内,后者相当于:
vars()[name] = value
更简洁一点,但在函数(vars()中不起作用
给出了它调用的作用域的变量:在全局作用域调用时模块的变量,然后可以使用它R/W,但在函数中调用时函数的变量,然后必须将其视为R/O——Python在线文档可能会对这一特定区别有点混淆)
globals()[“某些常量”]=42
如果必须在模块内设置模块范围内的变量,
全局
有什么问题
# my_module.py
def define_module_scoped_variables():
global a, b, c
a, b, c = 'a', ['b'], 3
因此:
在Python3.7中,您将能够在模块级别()使用
\uuuu getattr\uuuu
Per:
文档给出了关于修改vars()的警告。什么时候可以这样做?@~unutbu,我并不是真的说“可以”,但当您在模块级作用域而不是在函数内部调用
vars()
时,它会起作用。vars()
相当于模块作用域中的globals()
(因此返回一个真实的、可修改的dict),但却相当于locals()
在函数范围内(因此返回一个永不修改的伪dict)。我在模块范围内使用了vars()
,因为它保存了3个字符,一个音节,而在该范围内的同义词是globals()
;-)是的,它会破坏Python编译器所做的最重要的优化:函数的局部变量不保存在dict中,它们位于一个紧密的值向量中,每个局部变量访问都使用该向量中的索引,而不是名称查找。要击败优化,迫使您想要存在的dict,请使用exec''
启动函数:每次对一个函数执行两个实质性循环,您就会看到这个核心优化对Python性能的重要性。@msw,我想您忘了“实用性胜过纯度”;-)。是的,一些在运行时计算的常量并不完全是常量。如果您无法使用globals()
,则必须进入另一个模块以修改其属性;这必然会引起人们的疑惑。常量和可变是相互排斥的。不包含常量和动态生成。我生成的值总是相同的,并根据进一步的“常量”确定,以节省我的算术和键入。是的,我总是(其中“总是”被定义为“我最近几个月一直在学习Python”)发现全局性的,但并不真的声明令人费解。我想这可能是模块名称空间之前的历史遗迹。最初的问题是如何设置名称由字符串给出的属性(与我目前搜索的内容相同),因此这没有帮助。
# my_module.py
def define_module_scoped_variables():
global a, b, c
a, b, c = 'a', ['b'], 3
>>> import my_module
>>> my_module.define_module_scoped_variables()
>>> a
NameError: name 'a' is not defined
>>> my_module.a
'a'
>>> my_module.b
['b']
def __getattr__(name):
if name == "SOME_CONSTANT":
return 42
raise AttributeError(f"module {__name__} has no attribute {name}")