11
votes

Utiliser des fonctions de décorateur Python à partir d'un module différent

Je souhaite utiliser une fonction d'un autre module en tant que décorateur, mais j'en ai besoin pour manipuler l'espace de noms global du module actuel.

Par exemple, je veux pouvoir partir de ceci: p>

from othermodule import decorator

@decorator
class Someclass:
    pass


3 commentaires

Ce code ne fonctionne-t-il pas déjà?


Je pense qu'il souhaite que le code de décorateur définisse une variable racine dans la portée mondiale de la classe d'origine. J'ai peur que ce soit contre tout python.


Vous pourriez avoir une fonction qui retourne le décorateur qui accepte vos globaux.


4 Réponses :


6
votes

qui fonctionne déjà:

def decorator(cls):
    #.... do something with cls
    return cls


1 commentaires

Oui, je sais que cela fonctionne en général, mais c'est le fait que je souhaite un décorateur du module importé pour définir une variable dans la portée globale du module d'origine qui provoque des problèmes.



3
votes

Ceci est un peu hacky, mais essayez ceci dans autreModule.py : xxx


4 commentaires

Ouais qui fonctionnait, merci. En fait, j'ai fini par utiliser mod = sys.modules [CLS .__ module__] car l'appel Import renvoyé uniquement le module de niveau supérieur (CLS .__ Module__) était de 4 niveaux profond - c'est-à-dire mod1.mod2.mod3.mod4


Incidemment, mod = __import __ (CLS .__ module__, {}, {}, ('*',)) retournerait le module MOD4, pas le package mod1 extérieur


Ceci est une réponse directe (bien que celles-ci pour les packages et telle), mais un code très effrayant. En outre, il est en quelque sorte idiot d'utiliser setattr avec littéraux de chaîne. Seattr (FOO, 'BAR', BAZ) est orthographié foo.bar = Baz .


Oui, le Setattr était excessif. Je l'ai supprimé. Le code n'est pas tout ce qui effrayant: Module est un attribut documenté des classes. Si l'OP devrait réellement le faire du tout est bien sûr une autre question.



6
votes

Avoir un décorateur Modifier l'espace de noms global si tout module , encore moins un autre module est mauvais et jamais nécessaire. Le code qui muttait des globaux lointains est difficile à lire et à entretenir. Vous devez certainement envisager de modifier votre conception pour éviter l'état mondial mutable et une affectation particulièrement implicite.


0 commentaires

0
votes

Au lieu d'un décorateur direct, vous pouvez avoir une fonction qui renvoie un décorateur et accepte les globaux de votre module: xxx


0 commentaires