猴子补丁Python类
我有一个类,它在一个单独的模块里,我不能对它进行修改。
from module import MyClass
class ReplaceClass(object)
...
MyClass = ReplaceClass
这段代码只会在这个文件里改变 MyClass,其他地方不会受到影响。不过,如果我添加一个像这样的函数
def bar():
print 123
MyClass.foo = bar
那么这个函数就会在其他地方也能用。
我该怎么完全替换这个类呢?
4 个回答
17
我还是个菜鸟……也许对老手来说这很明显,但我需要用到 from some.package.module import module
这种写法。
我需要修改一个叫 GenerallyHelpfulClass 的类里的方法。结果失败了:
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
这种写法是“获取模块”,正如 Alex 所说的,它会被包里的其他模块识别到。进一步推测,长点的点分引用似乎是把模块引入到当前的命名空间,但并不会改变其他命名空间使用的模块。因此,对引入的模块所做的修改只会在做修改的那个命名空间里生效。就好像有两个相同的模块,每个模块在不同的引用下可用。
40
尽量避免使用 from ... import
这种方式来获取简单的名称,因为你最常需要的是带有模块名的名称。如果你按照正确的Python方式来做:
import module
class ReplaceClass(object): ...
module.MyClass = ReplaceClass
这样做,你实际上是在修改模块对象,这正是你需要的,并且在这个模块被其他地方使用时也能正常工作。而使用 from ...
的方式,你根本就没有模块对象(这就是大多数人使用 from ...
时的一个明显缺陷),所以你显然会处于不利的状态;-)
我唯一推荐使用 from
语句的情况是从一个包中导入模块:
from some.package.here import amodule
这样你仍然可以获取模块对象,并且会对该模块中的所有名称使用带有模块名的名称。
79
import module
class ReplaceClass(object):
....
module.MyClass = ReplaceClass
当然可以!请把你想要翻译的内容发给我,我会帮你把它变得更简单易懂。