如何通过猴子修补来替换类?

发布于 2024-09-24 19:56:56 字数 2074 浏览 8 评论 0原文

我如何替换 ORM 类 - 所以它不应该导致递归!

问题
原始类有 super 调用,当它被替换时 - 它会导致自继承并导致最大递归深度超出异常。
即类orm正在调用super(orm, self)....并且orm已被另一个继承原始orm的类替换....

包!

addons  __init__.py  osv  run_app.py

./addons:
__init__.py  test_app1.py  test.py

./osv:
__init__.py  orm.py

orm.py 的内容

class orm_template(object):
    def __init__(self, *args, **kw):
        super(orm_template, self).__init__()    
    def fields_get(self, fields):
        return fields    
    def browse(self, id):
        return id

class orm(orm_template):
    def __init__(self, *args, **kw):
        super(orm, self).__init__(*args, **kw)    
    def fields_get(self, fields, context = None):
        return super(orm, self).fields_get(fields)    
    def read(self, fields):
        return fields

addons/init.py

import test    
def main(app):
    print "Running..."
    __import__(app, globals(), locals())

的内容 addons/test.py

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.........................."

的内容 test_app1.py 的

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'])

内容 run_app.py 的内容

import addons
addons.main('test_app1')

输出

>>>python run_app.py

replaced..........................
Running...
...
...
super(orm, self).__init__(*args, **kw)
RuntimeError: maximum recursion depth exceeded

我见过类似的 问题

How can I replace the ORM class - so it should not cause recursion !!!

Problem:
original class has the super call, when its got replaced - it causes self inheritance and causes maximum recursion depth exceed exception.
i.e. class orm is calling super(orm, self).... and orm has been replaced by another class which inherits original orm....

Package !

addons  __init__.py  osv  run_app.py

./addons:
__init__.py  test_app1.py  test.py

./osv:
__init__.py  orm.py

contents of orm.py

class orm_template(object):
    def __init__(self, *args, **kw):
        super(orm_template, self).__init__()    
    def fields_get(self, fields):
        return fields    
    def browse(self, id):
        return id

class orm(orm_template):
    def __init__(self, *args, **kw):
        super(orm, self).__init__(*args, **kw)    
    def fields_get(self, fields, context = None):
        return super(orm, self).fields_get(fields)    
    def read(self, fields):
        return fields

contents of addons/init.py

import test    
def main(app):
    print "Running..."
    __import__(app, globals(), locals())

contents of addons/test.py

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.........................."

contents of test_app1.py

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'])

contents of run_app.py

import addons
addons.main('test_app1')

OUTPUT

>>>python run_app.py

replaced..........................
Running...
...
...
super(orm, self).__init__(*args, **kw)
RuntimeError: maximum recursion depth exceeded

I've seen the similar question

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

如果没结果 2024-10-01 19:56:56

您的 addons/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)来避免猴子修补,您会更高兴;-)。

Your addons/test.py needs to get and keep a reference to the original orm.orm and use that instead of the replaced version. I.e.:

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.........................."

so the monkeypatched-in class inherit from the original rather than from itself, as you had it in your setup. BTW, if you can avoid monkey-patching by better design of the osv module (e.g. w/a setter function to set what's the orm) you'll be happier;-).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文