如何在当前模块中调用setattr()?

172 投票
4 回答
75617 浏览
提问于 2025-04-15 23:18

我在调用函数 setattr(object, name, value) 时,应该把什么作为第一个参数 "object" 传进去,以便在当前模块中设置变量呢?

举个例子:

setattr(object, "SOME_CONSTANT", 42);

这样做的效果和:

SOME_CONSTANT = 42

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

我在模块级别动态生成几个值,由于我不能在模块级别定义 __getattr__,所以这是我的备用方案。

4 个回答

6

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

# 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']
15

在Python 3.7中,你可以在模块级别使用 __getattr__ 这个功能(相关回答)。

根据 PEP 562 的说明:

def __getattr__(name):
    if name == "SOME_CONSTANT":
        return 42
    raise AttributeError(f"module {__name__} has no attribute {name}")
284
import sys

thismodule = sys.modules[__name__]

setattr(thismodule, name, value)

或者,不使用 setattr(虽然这样不完全符合问题的要求,但在实际应用中可以达到相同的效果;-):

globals()[name] = value

注意:在模块范围内,后者等同于:

vars()[name] = value

这个写法稍微简洁一些,但在函数内部是无法使用的(vars() 会返回它被调用时的作用域中的变量:在全局范围内调用时返回模块的变量,这样可以进行读写;但在函数内部调用时返回的是函数的变量,这时只能进行读取,不能写入——Python的在线文档在这个具体的区别上可能会让人感到困惑)。

撰写回答