Python 如何用猴子补丁替换类?

Python 如何用猴子补丁替换类?,python,class,monkeypatching,Python,Class,Monkeypatching,如何替换ORM类-这样它就不会导致递归 问题: 原始类具有超级调用,当其被替换时-它会导致自继承并导致最大递归深度超出异常。 i、 类orm正在调用超级(orm,self)。。。。orm已经被另一个继承了原始orm的类所取代 包裹 orm.py的内容 插件的内容/init.py addons/test.py的内容 测试内容_app1.py run_app.py的内容 输出 我见过类似的您的插件/test.py需要获取并保留对原始orm.orm的引用,并使用它来代替替换的版本。即: from os

如何替换ORM类-这样它就不会导致递归

问题:
原始类具有超级调用,当其被替换时-它会导致自继承并导致最大递归深度超出异常。
i、 类orm正在调用超级(orm,self)。。。。orm已经被另一个继承了原始orm的类所取代

包裹 orm.py的内容 插件的内容/init.py addons/test.py的内容 测试内容_app1.py run_app.py的内容 输出
我见过类似的

您的
插件/test.py
需要获取并保留对原始
orm.orm
的引用,并使用它来代替替换的版本。即:

from osv import orm
import osv
original_orm = osv.orm
class orm(original_orm):
    def __init__(self, *args, **kw):
        super(orm, self).__init__(*args, **kw)    
    def fields_get(self, *args, **kw):
        print "my fields get................."
        return super(orm, self).fields_get(*args, **kw)    
osv.orm.orm = orm
print "replaced.........................."

因此,monkeypatched in类继承自原始类,而不是您在设置中使用的自身。顺便说一句,如果您可以通过更好地设计
osv
模块(例如,使用setter函数来设置orm)来避免猴子补丁,您会更高兴;-)

您的
插件/test.py
需要获取并保留对原始
orm.orm
的引用,并使用该引用代替替换版本。即:

from osv import orm
import osv
original_orm = osv.orm
class orm(original_orm):
    def __init__(self, *args, **kw):
        super(orm, self).__init__(*args, **kw)    
    def fields_get(self, *args, **kw):
        print "my fields get................."
        return super(orm, self).fields_get(*args, **kw)    
osv.orm.orm = orm
print "replaced.........................."

因此,monkeypatched in类继承自原始类,而不是您在设置中使用的自身。顺便说一句,如果您可以通过更好地设计
osv
模块(例如,使用setter函数来设置orm)来避免猴子补丁,您会更高兴;-)

没错!,但我没有接触orm/osv的权限……我需要修改一些功能,以便与使用web服务的另一个平台集成……@shahjapan,正如我在A中所说,“如果你能避免”,等等——如果你绝对不能,那么monkeypatching虽然是一种非常糟糕的方法,但有时(不经常)可能是最小的邪恶(需要更多的细节来确定这是一种罕见的情况,还是一种更常见的情况,其中简单的间接寻址&c当然是完全足够的)。它起到了作用,但也需要对您的答案进行细微的更改返回super(original_orm,self)。fields_get(*args,**kw)由于方法也导致了同样的最大递归深度超出问题…是的!但我没有接触orm/osv的权限…并且我需要修改一些函数,以便与使用web服务的另一个平台集成…@shahjapan,正如我在A中所说的,“如果可以避免的话”,等等——如果你绝对不能,那么monkeypatching虽然是一种真正可怕的方法,但有时(不经常)可能是最小的邪恶(需要更多的细节来确定这是罕见的情况之一,还是更常见的情况,其中简单的间接寻址&c当然就足够了)。它起作用了,但也需要对您的答案进行细微更改,返回super(原始表单,self)。字段获取(*args,**kw)作为方法也会导致相同的最大递归深度超出问题。。。
import test    
def main(app):
    print "Running..."
    __import__(app, globals(), locals())
from osv import orm
import osv
class orm(orm.orm):
    def __init__(self, *args, **kw):
        super(orm, self).__init__(*args, **kw)    
    def fields_get(self, *args, **kw):
        print "my fields get................."
        return super(orm, self).fields_get(*args, **kw)    
osv.orm.orm = orm
print "replaced.........................."
from osv.orm import orm    
class hello(orm):
    _name = 'hellos'    
    def __init__(self, *args, **kw):
        super(hello, self).__init__(*args, **kw)    
print hello('test').fields_get(['name'])
import addons
addons.main('test_app1')
>>>python run_app.py

replaced..........................
Running...
...
...
super(orm, self).__init__(*args, **kw)
RuntimeError: maximum recursion depth exceeded
from osv import orm
import osv
original_orm = osv.orm
class orm(original_orm):
    def __init__(self, *args, **kw):
        super(orm, self).__init__(*args, **kw)    
    def fields_get(self, *args, **kw):
        print "my fields get................."
        return super(orm, self).fields_get(*args, **kw)    
osv.orm.orm = orm
print "replaced.........................."