RecursionError:获取对象的str时超出了最大递归深度

时间:2018-04-16 07:31:49

标签: python recursion python-3.5

关于这个问题在这里看了太多的例子,但是不能理清我的例子。

任何sugegstion将会欣赏,已经有他的recursiona dd无法解决问题。

tree = {}

def populate_node(account):
    node = '%(LOGIN)s,%(server_id)s' % account
    tree[node]['login'] = account['LOGIN']
    tree[node]['email'] = account['EMAIL'].lower()
    tree[node]['server_id'] = account['server_id']

for account in accounts:
    node = '%(LOGIN)s,%(server_id)s' % account
    parent = None
    if account['AGENT_ACCOUNT']:
        parent = '%(AGENT_ACCOUNT)s,%(server_id)s' % account
    if node not in tree:
        tree[node] = {}
    populate_node(account)
    if parent:
        tree[node]['parent'] = parent
        if parent not in tree:
            tree[parent] = {
                'login': parent,
                'server_id': account['server_id'],
                'children': [node],
            }
        else:
            if 'children' not in tree[parent]:
                tree[parent]['children'] = [node]
            else:
                tree[parent]['children'].append(node)

def get_path(node, tree):
    parent = node.get('parent')
    node_login = str(str(node.get('login')) + ',' + str(node.get('server_id')))
    if not parent:
       return []
    elif parent == node_login:
       return [parent]
    path = get_path(tree[parent], tree)
    return [parent] + path


for k, v in tree.items():
      v['path'] = get_path(v, tree)
      v['level'] = len(v['path']) + (1 if v['login'] != v.get('parent') else 0)

默认情况下:

tree = {}

节点是tree的项目。

示例树:

tree = {
    '1987,mt4-demo-0': {
        'login': 1987,
        'email': 'email_1',
        'server_id': 'mt4-demo-0'
    },
    '16044,mt4-demo-0': {
        'login': 16044,
        'email': 'email_2',
        'server_id': 'mt4-demo-0'
    },
    '160877748,mt4-demo-0': {
        'login': 160877748,
        'email': 'email_3',
        'server_id': 'mt4-demo-0'
    }
}

并且在这个递归错误中得到了每一个

RecursionError: maximum recursion depth exceeded while getting the str of an object

2 个答案:

答案 0 :(得分:10)

您的代码假定您始终处理acyclic directed graph,但您的输入中至少有一个directed cycle,其中一个AGENT_ACCOUNT引用直接或间接指向另一个帐户turn有一个AGENT_ACCOUNT值,指向第一个帐户。

例如,如果accounts设置为:

accounts = [
    {'LOGIN': 'foo', 'EMAIL': 'foo@bar.com', 'server_id': 'server 1',
     'AGENT_ACCOUNT': 'bar'},
    {'LOGIN': 'bar', 'EMAIL': 'bar@bar.com', 'server_id': 'server 1',
     'AGENT_ACCOUNT': 'foo'}]

然后tree变为:

{'bar,server 1': {'children': ['foo,server 1'],
                  'email': 'bar@bar.com',
                  'login': 'bar',
                  'parent': 'foo,server 1',
                  'server_id': 'server 1'},
 'foo,server 1': {'children': ['bar,server 1'],
                  'email': 'foo@bar.com',
                  'login': 'foo',
                  'parent': 'bar,server 1',
                  'server_id': 'server 1'}}

请注意,foo的{​​{1}}指向AGENT_ACCOUNTbar指向bar,形成一个周期。

这将在这两个条目中的任何一个上产生无限递归错误:

foo

您可以早期检测此类周期并退出并显示更清晰的错误消息:

>>> get_path(tree['bar,server 1'], tree)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 8, in get_path
  File "<stdin>", line 8, in get_path
  File "<stdin>", line 8, in get_path
  [Previous line repeated 994 more times]
  File "<stdin>", line 2, in get_path
RecursionError: maximum recursion depth exceeded while calling a Python object

现在在同一def get_path(node, tree, seen=None): if seen is None: seen = set() parent = node.get('parent') if parent: if parent in seen: raise ValueError( 'Already handled {!r}, cycle detected. ' 'Check all of {}'.format( parent, sorted(seen))) seen.add(parent) node_login = '{0[login]},{0[server_id]}'.format(node) # cleaner method to generate the key if not parent: return [] elif parent == node_login: return [parent] path = get_path(tree[parent], tree, seen) # pass seen along to recursive calls return [parent] + path 上运行此更新版本会产生:

tree

我认为这样的周期是错误的。如果不是,只需使用>>> get_path(tree['bar,server 1'], tree) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 16, in get_path File "<stdin>", line 16, in get_path File "<stdin>", line 9, in get_path ValueError: Already handled 'foo,server 1', cycle detected. Check all of ['bar,server 1', 'foo,server 1']fted by one space 将路径返回到该点(因此忽略循环),但是您将拥有循环的每个成员的路径版本,每个路径都是旋转版本的下。

您应该真正修复帐户信息,并删除此类周期。如果您需要找到所有这样的周期,您可以使用:

if  parent in seen: return []

答案 1 :(得分:0)

我收到了相同的错误消息,为我修复的是传递模型而不是返回模型。

我不得不使用这个:

class User(AbstractUser):
    pass

下面的代码不允许将模型传递给其他模型。

class User(AbstractUser):
    def __str__(self):
        return f"{self}"