问题:如何在当前模块上调用setattr()?

如何将第一个参数“ object”传递给函数setattr(object, name, value),以在当前模块上设置变量?

例如:

setattr(object, "SOME_CONSTANT", 42);

具有与以下相同的效果:

SOME_CONSTANT = 42

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

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

What do I pass as the first parameter “object” to the function setattr(object, name, value), to set variables on the current module?

For example:

setattr(object, "SOME_CONSTANT", 42);

giving the same effect as:

SOME_CONSTANT = 42

within the module containing these lines (with the correct object).

I’m generate several values at the module level dynamically, and as I can’t define __getattr__ at the module level, this is my fallback.


回答 0

import sys

thismodule = sys.modules[__name__]

setattr(thismodule, name, value)

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

globals()[name] = value

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

vars()[name] = value

这更加简洁,但是在函数内部不起作用(vars()给出在其范围内调用的变量:在全局范围内调用时模块的变量,然后可以使用R / W,但在函数中可以使用变量在函数中调用时,然后必须将其视为R / O - Python在线文档对此特定区别可能会造成混淆。

import sys

thismodule = sys.modules[__name__]

setattr(thismodule, name, value)

or, without using setattr (which breaks the letter of the question but satisfies the same practical purposes;-):

globals()[name] = value

Note: at module scope, the latter is equivalent to:

vars()[name] = value

which is a bit more concise, but doesn’t work from within a function (vars() gives the variables of the scope it’s called at: the module’s variables when called at global scope, and then it’s OK to use it R/W, but the function’s variables when called in a function, and then it must be treated as R/O — the Python online docs can be a bit confusing about this specific distinction).


回答 1

如果必须从模块内部设置模块范围的变量,那有什么问题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']

If you must set module scoped variables from within the module, what’s wrong with global?

# my_module.py

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

thus:

>>> import my_module
>>> my_module.define_module_scoped_variables()
>>> a
NameError: name 'a' is not defined
>>> my_module.a
'a'
>>> my_module.b
['b']

回答 2

在Python 3.7中,您将可以__getattr__在模块级别使用(相关答案)。

根据PEP 562

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

In Python 3.7, you will be able to use __getattr__ at the module level (related answer).

Per PEP 562:

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

回答 3

  1. 你不会的 你会做globals()["SOME_CONSTANT"] = 42
  2. 你不会的 您会将动态生成的内容存储在模块以外的其他位置。
  1. You wouldn’t. You would do globals()["SOME_CONSTANT"] = 42
  2. You wouldn’t. You would store dynamically-generated content somewhere other than a module.

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。