web-dev-qa-db-fra.com

Comment appeler setattr () sur le module actuel?

Qu'est-ce que je passe comme premier paramètre "object" à la fonction setattr(object, name, value), pour définir des variables sur le module actuel?

Par exemple:

setattr(object, "SOME_CONSTANT", 42);

donnant le même effet que:

SOME_CONSTANT = 42

dans le module contenant ces lignes (avec le bon object).

Je génère dynamiquement plusieurs valeurs au niveau du module, et comme je ne peux pas définir __getattr__ au niveau du module, c'est ma solution de rechange.

125
Matt Joiner
import sys

thismodule = sys.modules[__name__]

setattr(thismodule, name, value)

ou, sans utiliser setattr (qui casse la lettre de la question mais remplit les mêmes fonctions pratiques ;-):

globals()[name] = value

Note: au niveau du module, ce dernier équivaut à:

vars()[name] = value

ce qui est un peu plus concis, mais ne fonctionne pas à l'intérieur d'une fonction (vars() donne les variables de la portée à laquelle il est appelé: les variables du module lorsqu'il est appelé à la portée globale, puis il est OK de l'utiliser R/W, mais les variables de la fonction lorsqu'elles sont appelées dans une fonction, puis elles doivent être traitées comme R/O - les documents en ligne Python peuvent être un peu déroutants à propos de cette distinction spécifique).

194
Alex Martelli

Si vous devez définir des variables de portée de module à partir du module, quel est le problème avec global?

# my_module.py

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

ainsi:

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

Dans Python 3.7, vous pourrez utiliser __getattr__ au niveau du module ( réponse associée ).

Par PEP 562 :

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