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

Mat*_*ner 128 python module global-variables setattr getattr

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

例如:

setattr(object, "SOME_CONSTANT", 42);
Run Code Online (Sandbox Code Playgroud)

产生同样的效果:

SOME_CONSTANT = 42
Run Code Online (Sandbox Code Playgroud)

在包含这些行的模块中(正确object).

我在模块级别动态生成多个值,而我无法__getattr__在模块级别定义,这是我的后备.

Ale*_*lli 200

import sys

thismodule = sys.modules[__name__]

setattr(thismodule, name, value)
Run Code Online (Sandbox Code Playgroud)

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

globals()[name] = value
Run Code Online (Sandbox Code Playgroud)

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

vars()[name] = value
Run Code Online (Sandbox Code Playgroud)

这是一个更简洁,但不能在函数内工作(vars()给出它所调用的范围的变量:在全局范围调用时模块的变量,然后可以使用它R/W,但函数的在函数中调用时的变量,然后它必须被视为R/O - Python在线文档可能会有点混淆这个特定的区别).

  • 是的,它会破坏Python编译器所做的最重要的一个优化:函数的局部变量不是**保存在一个字典中,它们是一个紧密的值向量,每个局部变量访问使用索引该向量,而不是名称查找.为了打败优化,强制你希望存在的dict,用`exec''启动函数`:定时一个带有几个实质循环的函数,你会看到这个核心优化对Python性能的重要性. (14认同)
  • 文档提供有关修改变量()的警告.http://docs.python.org/library/functions.html#vars.什么时候可以这样做? (9认同)
  • `vars()`相当于模块范围内的`globals()`(因此返回一个真正的,可修改的dict),但是在函数范围内的`locals()`(因此返回一个永远不会被修改的伪单词) .我在模块范围使用`vars()`因为它节省了3个字符,一个音节,相对于它的同义词 - 范围`globals()`;-) (4认同)
  • @msw,我想你忘记了"实用性胜过纯洁";-). (3认同)
  • @~unutbu,我不会说它很"好",但是当你在模块级范围而不是函数内调用`vars()`时它会起作用. (2认同)

msw*_*msw 6

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

# my_module.py

def define_module_scoped_variables():
    global a, b, c
    a, b, c = 'a', ['b'], 3
Run Code Online (Sandbox Code Playgroud)

从而:

>>> import my_module
>>> my_module.define_module_scoped_variables()
>>> a
NameError: name 'a' is not defined
>>> my_module.a
'a'
>>> my_module.b
['b']
Run Code Online (Sandbox Code Playgroud)


Tre*_*ner 5

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

根据PEP 562

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