gpt4 book ai didi

python - Odoo-9:通过 setattr 添加字段时出现 "RuntimeError: maximum recursion depth exceeded"

转载 作者:太空宇宙 更新时间:2023-11-03 17:17:03 25 4
gpt4 key购买 nike

我正在开发一个 Odoo 模块,其中不是直接在模型中定义字段,而是有一个名为 schema 的元组,其中包含所有字段。我在模型中定义了一个类方法,该方法从元组中读取每个字段并通过内省(introspection)在模型上创建它。

@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)

在 Odoo v8 中它工作正常,但在 v9 中它给出错误“RuntimeError:超出最大递归深度”

在 Odoo v9 fields.py 中 __getattr__ 定义如下(参见 https://github.com/odoo/odoo/blob/9.0/openerp/fields.py ):

def __getattr__(self, name):
""" Access non-slot field attribute. """
try:
return self._attrs[name]
except KeyError:
raise AttributeError(name)

而 __init__ 如下:

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__ 定义如下:

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

错误是:

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

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

最佳答案

经过一些调试和查看 fields.py ,很明显,Odoo 不再希望模块/应用程序代码使用点表示法访问初始化参数(又名初始化参数),因此使用 field.string 访问字段或 field.required 的名称来查明该字段是否是必需的,而不是不再是一段有效的代码。相反,现在应该从名为 args 的字典类型字段实例变量访问所有初始化参数。

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

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

我现在将代码修改如下:

def add_a_field(cls, field):
setattr(cls, field.args['string'], field)
pass

args 和 _attrs 在 fields.py 中定义如下:

_slots = {
'args': EMPTY_DICT, # the parameters given to __init__()
'_attrs': EMPTY_DICT, # the field's non-slot attributes

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

_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

关于python - Odoo-9:通过 setattr 添加字段时出现 "RuntimeError: maximum recursion depth exceeded",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33578426/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com