首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Odoo-9:在通过setattr添加字段时,"RuntimeError:最大递归深度超过“

Odoo-9:在通过setattr添加字段时,"RuntimeError:最大递归深度超过“
EN

Stack Overflow用户
提问于 2015-11-07 02:15:14
回答 1查看 2.1K关注 0票数 1

我正在处理一个Odoo模块,在这个模块中,我没有直接定义模型中的字段,而是有一个叫做schema的元组,它包含所有字段。我在模型中定义了一个类方法,它从元组读取每个字段,并通过内省在模型上创建它。

代码语言:javascript
复制
@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 ()内置方法。

代码语言:javascript
复制
def add_a_field(cls, field):
    setattr(cls, field.string, field)
    pass

它添加一个名称和标签相同的字段。

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

代码语言:javascript
复制
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):

代码语言:javascript
复制
def __getattr__(self, name):
    """ Access non-slot field attribute. """
    try:
        return self._attrs[name]
    except KeyError:
        raise AttributeError(name)

而__init__如下所示:

代码语言:javascript
复制
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__定义如下:

代码语言:javascript
复制
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

错误是:

代码语言:javascript
复制
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

知道该怎么解决这个问题吗?

EN

回答 1

Stack Overflow用户

发布于 2015-11-07 12:21:02

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

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

代码语言:javascript
复制
def add_a_field(cls, field):
    setattr(cls, field.string, field)
    pass

我现在将代码修改如下:

代码语言:javascript
复制
def add_a_field(cls, field):
    setattr(cls, field.args['string'], field)
    pass

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

代码语言:javascript
复制
_slots = {
    'args': EMPTY_DICT,             # the parameters given to __init__()
    '_attrs': EMPTY_DICT,           # the field's non-slot attributes

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

代码语言:javascript
复制
_slots = {
    '_attrs': EMPTY_DICT,           # dictionary of field attributes; it contains:
                                    #  - all attributes after __init__()
                                    #  - free attributes only after set_class_name()

因此,总之,模块/应用程序代码现在应该使用 should d.args‘’string‘或should d.args’‘required’,而不是直接使用点表示法,即field.string或field.required

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33578426

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档