<p>让我通过逐行检查代码来澄清:</p>
<pre><code>downlinestack = []
distributor=self
downlinestack += User.query(User.sponsor == distributor.key).fetch(99999999)
</code></pre>
<p>首先,您没有告诉我们<code>User.query</code>返回什么。我假设这是一个用户对象列表。所以现在<code>downlinestack</code>看起来是这样的:<code>[User1, User2, User3]</code></p>
^{pr2}$
<p>现在,<code>downline</code>包含从堆栈末尾弹出的单个用户,<code>User3</code>。在</p>
<pre><code> logging.info('downline: %s' %str(downline))
for person in downline:
</code></pre>
<p>这是您的错误:<code>User3</code><em>不可编辑</em>。这并不神秘:它不是那种物体。它不是一个可以依次迭代访问的项的集合。如果你想在这里迭代一些东西,<em>你必须自己生成iterable。在</p>
<p>有两种可能的方法。第一种方法是迭代用户.查询公司名称:</p>
<pre><code>distributor=self
downlinestack = User.query(User.sponsor == distributor.key).fetch(99999999)
while downlinestack:
top_person = downlinestack.pop()
logging.info('top_person: %s' %str(top_person))
for person in User.query(User.sponsor == top_person.key).fetch(99999999):
downlinestack.append(person)
</code></pre>
<p>您的另一个选择是将<code>downlinestack</code>放入列表列表中:</p>
<pre><code>distributor=self
downlinestack = [User.query(User.sponsor == distributor.key).fetch(99999999)]
while downlinestack:
downline_top = downlinestack.pop()
for person in downline_top:
downlinestack.append(User.query(User.sponsor == person.key).fetch(99999999))
logging.info('person: %s' %str(person.key.id()))
</code></pre>
<p>这两种方法都可以。在</p>
<p>我没有足够的上下文来测试上面的内容,但是我创建了自己的简化测试方案,只是为了说明这确实有效。在</p>
<pre><code>>>> query_tree = {0: [1, 2, 3], 1: [4, 5], 2: [6], 3: [7, 8, 9, 10], 4: [],
5: [11, 12], 6: [], 7: [], 8: [13], 9: [], 10: [], 11: [14],
12: [], 13: [], 14: []}
>>> stack = query_tree[0][:] #make a copy to avoid changes to `query_tree`
>>> while stack:
... top_person = stack.pop()
... print top_person
... for person in query_tree[top_person]:
... stack.append(person)
...
3
10
9
8
13
7
2
6
1
5
12
11
14
4
</code></pre>
<p>如您所见,这将打印出查询树中每个人的id(除了根id 0)。在</p>
<p>另一种方法是:</p>
<pre><code>>>> stack = [query_tree[0]]
>>> while stack:
... top_person_list = stack.pop()
... for person in top_person_list:
... print person
... stack.append(query_tree[person])
...
1
2
3
7
8
9
10
13
6
4
5
11
12
14
</code></pre>