1

ORM クラスを置き換えるにはどうすればよいですか - 再帰が発生しないはずです!!!

問題:
元のクラスにスーパー コールがあり、それが置き換えられると、自己継承が発生し、最大再帰深度超過例外が発生します。
つまり、クラス 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

似たような質問を見たことがある

4

1 に答える 1

5

オリジナル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モジュールのより良い設計(たとえば、オームを設定するためのセッター関数付き)によってモンキーパッチを回避できる場合は、より幸せになります;-)。

于 2010-09-23T18:17:40.417 に答える