我如何调用Python setattr()在流模块?

How do I call setattr() on the current module?

我应该将什么作为第一个参数"object传递给函数setattr(object, name, value)以在当前模块上设置变量?

例如:

1
setattr(object,"SOME_CONSTANT", 42);

具有与以下相同的效果:

1
SOME_CONSTANT = 42

在包含这些行的模块中(使用正确的object)。

我在模块级别动态生成了几个值,由于我无法在模块级别定义__getattr__,所以这是我的回退。


1
2
3
4
5
import sys

thismodule = sys.modules[__name__]

setattr(thismodule, name, value)

或者,不使用setattr(打破了问题的字母,但满足相同的实际目的;-):

1
globals()[name] = value

注:在模块范围内,后者相当于:

1
vars()[name] = value

这有点简洁,但不适用于函数内部(vars()给出了它调用的作用域的变量:在全局作用域调用时模块的变量,然后可以使用r/w,但在函数中调用时函数的变量,然后必须将其视为r/o——python联机文档可以有点confusing关于这个特定的区别)。


如果必须在模块内设置模块范围的变量,那么global有什么问题?

1
2
3
4
5
# my_module.py

def define_module_scoped_variables():
    global a, b, c
    a, b, c = 'a', ['b'], 3

因此:

1
2
3
4
5
6
7
8
>>> import my_module
>>> my_module.define_module_scoped_variables()
>>> a
NameError: name 'a' is not defined
>>> my_module.a
'a'
>>> my_module.b
['b']


在Python3.7中,您将能够在模块级使用__getattr__(相关答案)。

PEP 562:

1
2
3
4
def __getattr__(name):
    if name =="SOME_CONSTANT":
        return 42
    raise AttributeError(f"module {__name__} has no attribute {name}")

  • 你不会的,你会的。
  • 您不会。您将动态生成的内容存储在模块以外的其他地方。