以下代码在构建HTML输出字符串时以递归方式将字典列表处理为树。尝试从递归函数中访问output
字符串变量时,我收到范围访问错误。但是,在同一范围内访问nodes
列表对象没有问题 - 事实上,在添加output
var之前,函数工作正常。这是什么交易?
nodes = [
{ 'id':1, 'parent_id':None, 'name':'a' },
{ 'id':2, 'parent_id':None, 'name':'b' },
{ 'id':3, 'parent_id':2, 'name':'c' },
{ 'id':4, 'parent_id':2, 'name':'d' },
{ 'id':5, 'parent_id':4, 'name':'e' },
{ 'id':6, 'parent_id':None, 'name':'f' }
]
output = ''
def build_node(node):
output += '<li><a>'+node['name']+'</a>'
subnodes = [subnode for subnode in nodes if subnode['parent_id'] == node['id']]
if len(subnodes) > 0 :
output += '<ul>'
[build_node(subnode) for subnode in subnodes]
output += '</ul>'
output += '</li>'
return node
output += '<ul>'
node_tree = [build_node(node) for node in nodes if node['parent_id'] == None]
output += '</ul>'
import pprint
pprint.pprint(node_tree)
错误:
Traceback (most recent call last):
File "prog.py", line 23, in <module>
node_tree = [build_node(node) for node in nodes if node['parent_id'] == None]
File "prog.py", line 13, in build_node
output += '<li><a>'+node['name']+'</a>'
UnboundLocalError: local variable 'output' referenced before assignment
答案 0 :(得分:3)
错误源于此:
output = ''
def add(s):
output = output + s
相当于output+=s
。扩展形式中的两个output
- s指的是不同的范围。赋值设置局部变量,而右边的表达式引用全局(因为尚未设置本地)。
Python检测到此类冲突并引发错误。
其他人建议使用global
让Python知道两个output
- s引用全局范围,但由于你在这里连接字符串,所以在Python中使用这个任务有更好的习惯用法:
output_list = []
def add(s):
output_list.append(s)
# ...
output = ''.join(output_list)
这里你没有在函数中设置变量,因此不需要global
。来自所有调用的字符串将添加到列表中,最后使用''
(空字符串)作为分隔符进行连接。这比使用+=
添加字符串要快得多,因为Python中的字符串是不可变的,因此每次添加两个字符串时,Python都必须创建一个新字符串。这引入了大量的内存复制。
答案 1 :(得分:1)
def build_node(node):
global output
# proceed as before
答案 2 :(得分:1)
虽然您可以使用global
声明,但将output
作为参数传递会更加清晰。
Global variables are considered to bad practice如果有避免使用它们的好方法,你应该利用这些方法。