Il y a deux principaux problèmes que vous rencontrez ici:
-
__xxx__
méthodes sont seulement leva les yeux sur la classe
TypeError: can't set attributes of built-in/extension type 'module'
(1) signifie que toute solution devra également suivre le module a été examiné, sinon chaque module serait alors l'exemple de substitution de comportement; et (2) signifie que (1) n'est même pas possible... du moins pas directement.
Heureusement, sys.des modules n'est pas pointilleux sur ce qui se passe il y a donc un wrapper de travail, mais uniquement pour le module d'accès (c'est à dire import somemodule; somemodule.salutation('world')
; le même module d'accès vous devez tirer sur les méthodes de la classe de substitution et les ajouter à l' globals()
eiher avec une méthode personnalisée sur la classe (j'aime utiliser .export()
) ou avec une fonction générique (comme ceux déjà inclus dans la liste des réponses). Une chose à garder à l'esprit: si le wrapper est la création d'une nouvelle instance à chaque fois, et le globals solution n'est pas, vous vous retrouvez avec une subtile différence de comportement. Oh, et vous ne devez pas utiliser les deux en même temps-c'est l'un ou l'autre.
Mise à jour
De Guido van Rossum:
Il est en fait un hack qui est parfois utilisée et recommandée:
le module peut définir une classe avec la fonctionnalité désirée, puis à
à la fin, remplacer lui-même dans sys.modules avec une instance de cette classe
(ou avec la classe, si vous insistez, mais c'est généralement moins utiles).
E. g.:
# module foo.py
import sys
class Foo:
def funct1(self, <args>): <code>
def funct2(self, <args>): <code>
sys.modules[__name__] = Foo()
Cela fonctionne parce que l'importation de machines est activement à l'activation de ce
hack, et comme la dernière étape tire le réel module de
sys.modules, après le chargement. (Ce n'est pas un hasard. Le hack a été
proposé il y a longtemps et nous avons décidé de nous aimais assez pour le soutenir dans la
importer des machines.)
Donc, l'établi de façon à accomplir ce que vous voulez, c'est de créer une classe unique dans votre module, et que le dernier acte de la module de remplacer sys.modules[__name__]
avec une instance de votre classe -- et maintenant vous pouvez jouer avec __getattr__
/__setattr__
/__getattribute__
en tant que de besoin.