Python 相同的语句不同的位置导致不同的结果:局部变量;os";分配前参考

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

我编写代码以递归方式列出所有具有层次结构的目录和文件。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(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)