给出以下文件结构,
├── 0=ocfl_object_1.0
├── inventory.json
├── inventory.json.md5
├── v1
│ ├── content
│ │ ├── foo.xml
│ │ └── level1
│ │ └── level2
│ │ └── bar.txt
│ ├── inventory.json
│ └── inventory.json.md5
└── v2
├── content
│ └── duck.txt
├── inventory.json
└── inventory.json.md5
我想知道python的os.walk
函数是否有可能在Mac和Linux上以不同顺序返回文件夹?两者都使用python 3.5。
Mac:
In [15]: for root,folders,files in os.walk('foo/bar'):
...: print(folders,files)
...:
['v1', 'v2'] ['inventory.json', '0=ocfl_object_1.0', 'inventory.json.md5']
['content'] ['inventory.json', 'inventory.json.md5']
['level1'] ['foo.xml']
['level2'] []
[] ['bar.txt']
['content'] ['inventory.json', 'inventory.json.md5']
[] ['duck.txt']
在Linux上:
In [54]: for root,folders,files in os.walk('foo/bar'):
...: print(folders,files)
...:
['v2', 'v1'] ['inventory.json.md5', 'inventory.json', '0=ocfl_object_1.0']
['content'] ['inventory.json.md5', 'inventory.json']
[] ['duck.txt']
['content'] ['inventory.json.md5', 'inventory.json']
['level1'] ['foo.xml']
['level2'] []
[] ['bar.txt']
在Mac上,好像首先遇到文件夹v1
,而在Linux上看起来是v2
。关于为什么会如此的任何见解?
答案 0 :(得分:5)
参见documentation on os.walk
相关部分:
在版本3.5中已更改:此函数现在改为调用
os.scandir()
的os.listdir()
中,减少了对os.stat()
。
然后在os.scandir()
中输入:
返回与条目对应的
os.DirEntry
个对象的迭代器 在路径给定的目录中。 任意输入条目 订单,并且不包含特殊条目'.'
和'..'
。
无论listdir()
还是scandir()
,都以任意顺序返回两者。
简而言之-预计不会出现订单。
话虽如此,您应该可以基于此部分在循环中操纵dirnames
:
当 topdown 为
True
时,呼叫者可以就地修改 dirnames 列表。 (也许使用del
或slice
分配),而walk()
仅会递归 进入名称保留在 dirnames 中的子目录;这可以是 用于修剪搜索,强加特定的访问顺序,甚至 通知walk()
有关呼叫者创建或重命名的目录的信息 在再次恢复walk()
之前。当 topdown 是时,修改 dirnamesFalse
对步行的行为没有任何影响,因为自下而上 模式 dirnames 中的目录在 dirpath 本身之前生成 生成。
因此,如果您folders.sort()
可以根据您的sorted
顺序工作。我刚试过,它起作用。我还对关键部分加粗了 -folders
必须排序到位,os.walk()
才能接受订单:
for root,folders,files in os.walk('foo/bar'):
folders.sort() # <--- sort your folders to impose the order.
print(folders,files)