Python Odoo-9:“;运行时错误:超过最大递归深度;通过setattr添加字段时
我正在开发一个Odoo模块,在该模块中,我没有直接定义模型中的字段,而是使用一个名为schema的元组,它包含所有字段。我在模型中定义了一个classmethod,它从元组中读取每个字段,并通过内省在模型上创建它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 可以看出,此方法在元组上迭代,
@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