Как я могу назвать setattr() для текущего модуля?

Что мне передать в качестве первого параметра "object" функции setattr(object, name, value), чтобы установить переменные в текущем модуле?

Например:

setattr(object, "SOME_CONSTANT", 42);

дает тот же эффект, что и:

SOME_CONSTANT = 42

внутри модуля, содержащего эти строки (с правильным object).

Я генерирую несколько значений на уровне модуля динамически, и поскольку я не могу определить __getattr__ на уровне модуля, это мой резерв.

Ответ 1

import sys

thismodule = sys.modules[__name__]

setattr(thismodule, name, value)

или, не используя setattr (что нарушает букву вопроса, но удовлетворяет тем же практическим целям; -):

globals()[name] = value

Примечание: в области модуля последний эквивалентен:

vars()[name] = value

который является немного более кратким, но не работает изнутри функции (vars() дает переменные области, на которую он вызвал: переменные модуля при вызове в глобальной области действия, а затем это ОК, чтобы использовать его R/W, но функциональные переменные при вызове в функции, а затем его следует рассматривать как R/O - онлайн-документы Python могут немного запутываться в этом конкретном различии).

Ответ 2

Если вы должны установить переменные с областью действия модуля из модуля, что случилось с 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']

Ответ 3

В Python 3.7 вы сможете использовать __getattr__ на уровне модуля (связанный ответ).

По PEP 562:

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

Ответ 4

  • Ты бы не стал. Вы бы сделали globals()["SOME_CONSTANT"] = 42
  • Ты бы не стал. Вы сохранили бы динамически созданный контент где-то, кроме модуля.