Monkey-patch Python类

我有一个课,位于一个单独的模块,我不能改变。

from module import MyClass class ReplaceClass(object) ... MyClass = ReplaceClass 

这不会改变MyClass在其他地方,但这个文件。 但是,如果我会添加一个像这样的方法

 def bar(): print 123 MyClass.foo = bar 

这将工作,富方法将在其他地方提供。

我如何完全replace这个类?

 import module class ReplaceClass(object): .... module.MyClass = ReplaceClass 

避免from ... import (horrid ;-)的方式获取裸号,当你最需要经常是合格的名字。 一旦你做了正确的Pythonic方式:

 import module class ReplaceClass(object): ... module.MyClass = ReplaceClass 

通过这种方法,您可以模块化模块对象,这就是您需要的模块对象。 from ...forms,你只是没有模块对象(一种方法来看待大多数人使用的明显缺陷from ... ),所以你显然更糟糕;-);

我推荐使用from语句的一种方法是从包中导入一个模块:

 from some.package.here import amodule 

所以你仍然得到模块对象,并将使用该模块中所有名称的限定名称。

我只是一个蛋。 。 。 。 也许这对于非新手来说是显而易见的,但是我需要from some.package.module import module成语。

我不得不修改一个GeneralHelpfulClass的方法。 这失败了:

 import some.package.module class SpeciallyHelpfulClass(some.package.module.GenerallyHelpfulClass): def general_method(self):... some.package.module.GenerallyHelpfulClass = SpeciallyHelpfulClass 

代码运行,但没有使用重载到SpeciallyHelpfulClass上的行为。

这工作:

 from some.package import module class SpeciallyHelpfulClass(module.GenerallyHelpfulClass): def general_method(self):... module.GenerallyHelpfulClass = SpeciallyHelpfulClass 

我推测, from ... import成语'获取模块',如亚历克斯写道,因为它将被包中的其他模块拾取。 进一步推测,较长的虚线引用似乎通过长点引用将模块引入到名称空间中,但不会更改其他名称空间使用的模块。 因此对导入模块的更改只会出现在它们所在的名称空间中。 就好像有两个相同模块的副本,每个副本都可以在略有不同的引用下使用。

 import some_module_name class MyClass(object): ... #copy/paste source class and update/add your logic some_module_name.MyClass = MyClass 

最好不要在更换时更改类的名称,因为不知何故某人可能使用getattr引用它们 – 这将导致如下的失败

getattr(some_module_name, 'MyClass') – >如果你用ReplaceClass取代了MyClass,将会失败!