这里有两个基本问题:
> __xxx__方法只在类上查找
> TypeError:不能设置内置/扩展类型’module’的属性,
(1)意味着任何解决方案都必须跟踪哪个模块正在被检查,否则每个模块将具有实例替换行为;和(2)意味着(1)甚至不可能…至少不直接。
幸运的是,sys.modules不是那么挑剔的,所以一个包装器将工作,但只有模块访问(即导入somemodule; somemodule.salutation(‘世界’);对于同模块访问,你几乎不得不嘲笑方法从替换类,并将它们添加到全局()eiher与类上的自定义方法(我喜欢使用.export())或一个通用的函数(如那些已经列出的答案)。需要注意的一点:如果包装器每次都在创建一个新的实例,而全局解决方案不是,那么你会遇到微妙的不同行为哦,你不能同时使用这两者 – 它是一个或另一个。
更新
There is actually a hack that is occasionally used and recommended: a
module can define a class with the desired functionality, and then at
the end, replace itself in sys.modules with an instance of that class
(or with the class, if you insist, but that’s generally less useful).
E.g.:
# module foo.py
import sys
class Foo:
def funct1(self, ):
def funct2(self, ):
sys.modules[__name__] = Foo()
This works because the import machinery is actively enabling this
hack, and as its final step pulls the actual module out of
sys.modules, after loading it. (This is no accident. The hack was
proposed long ago and we decided we liked enough to support it in the
import machinery.)
所以,完成你想要的方法是在模块中创建一个类,并且最后一个模块用你的类的实例替换sys.modules [__ name__] – 现在你可以使用__getattr __ / __setattr __ / __ getattribute__。