Jes*_*ose 3 python global-variables
我制作了一个从HTML文件中提取文本的程序.它递归HTML文档并返回标记列表.例如,
输入 <li>没办法<b>你</ b>正在这样做</ li>
输出 ['不','方式','你','是'...].
这是一个高度简化的伪代码:
def get_leaves(node):
kids=getchildren(node)
for i in kids:
if leafnode(i):
get_leaves(i)
else:
a=process_leaf(i)
list_of_leaves.append(a)
def calling_fn():
list_of_leaves=[] #which is now in global scope
get_leaves(rootnode)
print list_of_leaves
Run Code Online (Sandbox Code Playgroud)
我现在在调用函数的全局范围内使用list_of_leaves.calling_fn()声明了这个变量,get_leaves()追加到这个变量.
我的问题是,如何修改我的函数,以便我能够执行类似list_of_leaves = get_leaves(rootnode)的操作,即不使用全局变量?
我不希望函数的每个实例都复制列表,因为列表可能会变得非常大.
请不要批评这个特定伪代码的设计,因为我简化了这一点.它用于另一个目的:使用BeautifulSoup提取令牌以及相关标签
Imr*_*ran 11
您可以将结果列表作为可选参数传递.
def get_leaves(node, list_of_leaves=None):
list_of_leaves = [] if list_of_leaves is None else list_of_leaves
kids=getchildren(node)
for i in kids:
if leafnode(i):
get_leaves(i, list_of_leaves)
else:
a=process_leaf(i)
list_of_leaves.append(a)
def calling_fn():
result = []
get_leaves(rootnode, list_of_leaves=result)
print result
Run Code Online (Sandbox Code Playgroud)
Python对象总是通过引用传递.这种情况以前也讨论过这里.一些内置的类型是不可变的(例如int,string),所以你不能到位修改它们(当您连接两个字符串,并将其分配给一个变量,创建一个新的字符串).list可以修改可变类型(例如)的实例.我们通过将原始列表传递给我们的递归调用来利用这个优势.
为了在真实应用程序中从HTML中提取文本,使用成熟的库,BeautifulSoup或者lxml.html总是一个更好的选择(正如其他人所建议的那样).
如果get_leaves()转换为生成器,则无需将累加器传递给函数或通过全局名称访问它:
def get_leaves(node):
for child in getchildren(node):
if leafnode(child):
for each in get_leaves(child):
yield each
else:
yield process_leaf(child)
def calling_fn():
list_of_leaves = list(get_leaves(rootnode))
print list_of_leaves
Run Code Online (Sandbox Code Playgroud)