Python Odoo-9:“;运行时错误:超过最大递归深度;通过setattr添加字段时

Python Odoo-9:“;运行时错误:超过最大递归深度;通过setattr添加字段时,python,openerp,odoo-9,Python,Openerp,Odoo 9,我正在开发一个Odoo模块,在该模块中,我没有直接定义模型中的字段,而是使用一个名为schema的元组,它包含所有字段。我在模型中定义了一个classmethod,它从元组中读取每个字段,并通过内省在模型上创建它 @classmethod def initialze(cls, schema): for field in schema: add_a_field(cls, field) pass pass 可以看出,此方法在元组上迭代,

我正在开发一个Odoo模块,在该模块中,我没有直接定义模型中的字段,而是使用一个名为schema的元组,它包含所有字段。我在模型中定义了一个classmethod,它从元组中读取每个字段,并通过内省在模型上创建它

@classmethod
def initialze(cls, schema):
    for field in schema:
        add_a_field(cls, field)
        pass
    pass       
可以看出,此方法在元组上迭代,并将单个字段传递给另一个方法名“add_a_field(cls,field)”

方法“add_a_field”使用python setattr()内置方法

def add_a_field(cls, field):
    setattr(cls, field.string, field)
    pass
它会添加一个具有相同名称和标签的字段

在我使用此方法的类中,我直接调用它,如以下示例所示:

from openerp import fields, models
# other imports

def add_a_field(cls, field):
    setattr(cls, field.string, field)
    pass

schema = (
          fields.Char(string='RequestID'),
          fields.Float(string='Discount', default=0.00),
          fields.Float(string='Subtotal', default=0.00),
          )

class Batch(models.Model): 
    _name='batch'
    @classmethod
    def initialze(cls, schema):
        for field in schema:
            add_a_field(cls, field)
            pass
        pass       
    pass

# other model methods
Batch.initialze(schema)
在OdooV8中,它工作正常,但在v9中,它给出了一个错误“RuntimeError:超出了最大递归深度”

在Odoo v9中,fields.py\uuu getattr\uuuu的定义如下(请参阅):

而_uinit _uu如下所示:

def __init__(self, string=None, **kwargs):
        kwargs['string'] = string
        args = {key: val for key, val in kwargs.iteritems() if val is not None}
        self.args = args or EMPTY_DICT
        self.setup_full_done = False
在v8 fields.py中,init_uuuuu的定义如下:

def __init__(self, string=None, **kwargs):
        kwargs['string'] = string
        attrs = {key: val for key, val in kwargs.iteritems() if val is not None}
        self._attrs = attrs or EMPTY_DICT
def add_a_field(cls, field):
    setattr(cls, field.args['string'], field)
    pass
_slots = {
    '_attrs': EMPTY_DICT,           # dictionary of field attributes; it contains:
                                    #  - all attributes after __init__()
                                    #  - free attributes only after set_class_name()
错误是:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 6, in initialze
  File "<stdin>", line 2, in add_a_field
  File "openerp/fields.py", line 343, in __getattr__
    return self._attrs[name]
  File "openerp/fields.py", line 343, in __getattr__
    return self._attrs[name]
  File "openerp/fields.py", line 343, in __getattr__
    return self._attrs[name]
  File "openerp/fields.py", line 343, in __getattr__
    return self._attrs[name]
  File "openerp/fields.py", line 343, in __getattr__
    return self._attrs[name]
:
:
:
:
RuntimeError: maximum recursion depth exceeded while calling a Python object
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“”,第6行,初始值
文件“”,第2行,在添加字段中
文件“openerp/fields.py”,第343行,在__
返回自我。\u属性[名称]
文件“openerp/fields.py”,第343行,在__
返回自我。\u属性[名称]
文件“openerp/fields.py”,第343行,在__
返回自我。\u属性[名称]
文件“openerp/fields.py”,第343行,在__
返回自我。\u属性[名称]
文件“openerp/fields.py”,第343行,在__
返回自我。\u属性[名称]
:
:
:
:
RuntimeError:调用Python对象时超出了最大递归深度

知道应该如何解决这个问题吗?

在进行了一些调试并在中查看之后,很明显,Odoo不再希望模块/应用程序代码使用点表示法访问初始化参数,即init参数,因此使用field.string访问field或field.required的名称,以确定是否需要此字段,不再是一段有效的代码。相反,现在应该从名为args的字典类型字段实例变量访问所有初始化参数

当我在以下代码中访问field.string时,出现了运行时错误:

def add_a_field(cls, field):
    setattr(cls, field.string, field)
    pass
我现在修改代码如下:

def __init__(self, string=None, **kwargs):
        kwargs['string'] = string
        attrs = {key: val for key, val in kwargs.iteritems() if val is not None}
        self._attrs = attrs or EMPTY_DICT
def add_a_field(cls, field):
    setattr(cls, field.args['string'], field)
    pass
_slots = {
    '_attrs': EMPTY_DICT,           # dictionary of field attributes; it contains:
                                    #  - all attributes after __init__()
                                    #  - free attributes only after set_class_name()
args和_attr的定义如下所示:

在早期的Odoo v8中,没有args,而_attrs的定义如下:

def __init__(self, string=None, **kwargs):
        kwargs['string'] = string
        attrs = {key: val for key, val in kwargs.iteritems() if val is not None}
        self._attrs = attrs or EMPTY_DICT
def add_a_field(cls, field):
    setattr(cls, field.args['string'], field)
    pass
_slots = {
    '_attrs': EMPTY_DICT,           # dictionary of field attributes; it contains:
                                    #  - all attributes after __init__()
                                    #  - free attributes only after set_class_name()
因此,总之,模块/应用程序代码现在应该使用field.args['string']或field.args['required']而不是直接使用点符号,即field.string或field.required