Как я могу назвать 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
- Ты бы не стал. Вы сохранили бы динамически созданный контент где-то, кроме модуля.