Python 相同的语句不同的位置导致不同的结果:局部变量;os";分配前参考
我编写代码以递归方式列出所有具有层次结构的目录和文件。code1和code2之间只有一个区别,“导入操作系统”的位置。Python 相同的语句不同的位置导致不同的结果:局部变量;os";分配前参考,python,recursion,Python,Recursion,我编写代码以递归方式列出所有具有层次结构的目录和文件。code1和code2之间只有一个区别,“导入操作系统”的位置。 代码1: def recur_dir(dn,level=0,result=[]): import os new_queue=[] if level==0: dn=[dn] for item in dn: result.append([level,item]) if os.path.isdir(it
代码1:
def recur_dir(dn,level=0,result=[]):
import os
new_queue=[]
if level==0:
dn=[dn]
for item in dn:
result.append([level,item])
if os.path.isdir(item):
for next_item in os.listdir(item):
next_dn = os.path.join(item, next_item)
new_queue.append(next_dn)
level=level+1
if len(dn)>0: recur_dir(new_queue,level,result)
return result
>>> z=recur_dir("/home/jack",0,[])
>>> z
[[0, '/home/jack'], [1, '/home/jack/.ssh'], [1, '/home/jack/.profile'], [1, '/home/jack/.bashrc'], [1, '/home/jack/wp.sh'], [1, '/home/jack/.bash_history'], [1, '/home/jack/.bash_logout'], [2, '/home/jack/.ssh/known_hosts']]
我想在运行过程中只调用一次“导入操作系统”,将代码1更改为代码2
代码2:
def recur_dir(dn,level=0,result=[]):
new_queue=[]
if level==0:
dn=[dn]
import os
for item in dn:
result.append([level,item])
if os.path.isdir(item):
for next_item in os.listdir(item):
next_dn = os.path.join(item, next_item)
new_queue.append(next_dn)
level=level+1
if len(dn)>0: recur_dir(new_queue,level,result)
return result
>>> y=recur_dir("/home/jack",0,[])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 14, in recur_dir
File "<stdin>", line 9, in recur_dir
UnboundLocalError: local variable 'os' referenced before assignment
def recur_dir(dn,级别=0,结果=[]):
新队列=[]
如果级别==0:
dn=[dn]
导入操作系统
对于dn中的项目:
结果.追加([级别,项])
如果os.path.isdir(项目):
对于os.listdir(项目)中的下一个项目:
next\u dn=os.path.join(项,下一项)
新建队列。追加(下一个\u dn)
级别=级别+1
如果len(dn)>0:recurdir(新队列、级别、结果)
返回结果
>>>y=recur_dir(“/home/jack”,0,[]))
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“”,第14行,在重复目录中
文件“”,第9行,在重复目录中
UnboundLocalError:分配前引用的局部变量“os”
请告诉我代码背后的原因。因为
导入os
是在if
循环中定义的,所以当级别
为0
时,即if level==0:
此时只导入os
模块。当使用级别调用函数时,变量值不等于0
,如果条件为False
,则该时间,即导入os
语句不执行
在第一个例子中:
import os
是在函数开始时定义的,即每次调用时导入os
模块,我们可以在函数中访问os
。这就是为什么代码在第一个示例中起作用
在py文件开头定义模块的最佳方法
或
在函数中定义同级模块,函数可以访问同级或嵌套级模块
e、 g:
def测试(否):
... 如果否==0:
... 导入操作系统
... 打印“我是os:”,os
...
>>>测试(0)
我是os:
>>>测试(10)
我是os:
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“”,第4行,在测试中
UnboundLocalError:分配前引用的局部变量“os”
>>>
这个小实验将回答您的问题:
In [2]: def recur_dir(level=0):
if level==0:
import os
elif level == 2:
return
print globals().keys(), locals().keys()
recur_dir(level+1)
...:
In [3]: recur_dir(0)
['_dh', '__', 'help', 'quit', '__builtins__', 'recur_dir', '_ih', '__builtin__', '__name__', '___', '__package__', '_', '_sh', '_i3', '_i2', '_i1', '__doc__', '_iii', 'exit', 'get_ipython', '_i', 'In', '_ii', '_oh', 'Out']
['os', 'level']
['_dh', '__', 'help', 'quit', '__builtins__', 'recur_dir', '_ih', '__builtin__', '__name__', '___', '__package__', '_', '_sh', '_i3', '_i2', '_i1', '__doc__', '_iii', 'exit', 'get_ipython', '_i', 'In', '_ii', '_oh', 'Out']
['level']
正如您可能看到的,导入的操作系统不显示在全局范围中-它只添加到本地范围。随着递归的深入,您将创建一个新的本地作用域,它不包含操作系统 请注意,在回溯错误消息中:
Traceback (most recent call last):
File "/home/unutbu/pybin/script.py", line 21, in <module>
recur_dir('/tmp', 0, [])
File "/home/unutbu/pybin/script.py", line 18, in recur_dir
if len(dn)>0: recur_dir(new_queue,level,result) <- RECUR_DIR IS CALLED
File "/home/unutbu/pybin/script.py", line 13, in recur_dir
if os.path.isdir(item):
UnboundLocalError: local variable 'os' referenced before assignment
到达。换句话说,UnboundLocalError
在
第二次调用recur\u dir
,此时level
不再等于零
请记住,通过在recur\u dir
内部使用import os
,os
被定义为局部变量。它只存在于功能范围内。第二次递归调用recur\u dir
时,未定义os
。因此,在第13行遇到os
时出现UnboundLocalError。因为import os
是在if loop内部定义的。请提供更多详细信息?为什么不将import os
放在函数外部?
Traceback (most recent call last):
File "/home/unutbu/pybin/script.py", line 21, in <module>
recur_dir('/tmp', 0, [])
File "/home/unutbu/pybin/script.py", line 18, in recur_dir
if len(dn)>0: recur_dir(new_queue,level,result) <- RECUR_DIR IS CALLED
File "/home/unutbu/pybin/script.py", line 13, in recur_dir
if os.path.isdir(item):
UnboundLocalError: local variable 'os' referenced before assignment
if len(dn)>0: recur_dir(new_queue,level,result)