猴子补丁 Python 类
我有一个类,位于一个单独的模块中,我无法更改它。
from module import MyClass
class ReplaceClass(object)
...
MyClass = ReplaceClass
除了这个文件之外,这不会改变 MyClass 的其他任何地方。但是,如果我像这样向类添加一个方法,
def bar():
print 123
MyClass.foo = bar
它将起作用,但 foo 方法也将在其他地方可用。
如何完全替换类而不是替换方法呢?
I've got a class, located in a separate module, which I can't change.
from module import MyClass
class ReplaceClass(object)
...
MyClass = ReplaceClass
This doesn't change MyClass anywhere else but this file. However if I add a method to the class like this
def bar():
print 123
MyClass.foo = bar
it will work, but the foo method will be available everywhere else as well.
How can I replace the class completely instead of replacing the method?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
当您最需要的是限定名称时,请避免使用
from ... import
(可怕的;-)方式来获取裸名。一旦你以正确的 Python 方式做事:这样,你就可以对 module 对象进行猴子修补,这就是你所需要的,并且当该模块用于其他模块时它将起作用。使用
from ...
形式,您只是没有拥有模块对象(这是查看大多数人使用from 的明显缺陷的一种方法。 ..
),所以你的情况显然更糟;-);我建议使用
from
语句的一种方法是从包中导入模块:这样您仍然可以获得模块对象,并且对该模块中的所有名称使用限定名称。
Avoid the
from ... import
(horrid;-) way to get barenames when what you need most often are qualified names. Once you do things the right Pythonic way:This way, you're monkeypatching the module object, which is what you need and will work when that module is used for others. With the
from ...
form, you just don't have the module object (one way to look at the glaring defect of most people's use offrom ...
) and so you're obviously worse off;-);The one way in which I recommend using the
from
statement is to import a module from within a package:so you're still getting the module object and will use qualified names for all the names in that module.
我不过是一颗鸡蛋。 。 。 。也许这对于非新手来说是显而易见的,但我需要
from some.package.module import module
习惯用法。我必须修改 GeneralHelpfulClass 的一种方法。这失败了:
代码运行了,但没有使用重载到 SpeciallyHelpfulClass 上的行为。
这有效:
我推测
from ... import
习惯用法“获取模块”,正如 Alex 所写,因为它将被包中的其他模块拾取。进一步推测,较长的点引用似乎通过长点引用导入将模块带入命名空间,但不会更改其他命名空间使用的模块。因此,对导入模块的更改只会出现在进行更改的名称空间中。就好像同一模块有两个副本,每个副本都可以在略有不同的参考下使用。I am but an egg . . . . Perhaps it is obvious to not-newbies, but I needed the
from some.package.module import module
idiom.I had to modify one method of GenerallyHelpfulClass. This failed:
The code ran, but didn't use the behaviors overloaded onto SpeciallyHelpfulClass.
This worked:
I speculate that the
from ... import
idiom 'gets the module', as Alex wrote, as it will be picked up by other modules in the package. Speculating further, the longer dotted reference seems to bring the module into the namespace with the import by long dotted reference, but doesn't change the module used by other namespaces. Thus changes to the import module would only appear in the name space where they were made. It's as if there were two copies of the same module, each available under slightly different references.最好不要在替换时更改类的名称,因为不知何故有人可能使用 getattr 引用了它们 - 这将导致失败,如下所示
getattr(some_module_name, 'MyClass')
-->如果你用 ReplaceClass 替换了 MyClass ,这将会失败!Its preferable not to change the name of class while replacing, because somehow someone may have referenced them using getattr - which will result in fail like below
getattr(some_module_name, 'MyClass')
--> which will fail if you have replaced MyClass by ReplaceClass !