os.walk在Mac和Linux上使用不同的文件夹顺序吗?

时间:2019-02-19 19:27:26

标签: python linux macos python-3.5 os.walk

给出以下文件结构,

├── 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。关于为什么会如此的任何见解?

1 个答案:

答案 0 :(得分:5)

参见documentation on os.walk相关部分:

  

在版本3.5中已更改:此函数现在改为调用os.scandir()   的os.listdir()中,减少了对   os.stat()

然后在os.scandir()中输入:

  

返回与条目对应的os.DirEntry个对象的迭代器   在路径给定的目录中。 任意输入条目   订单,并且不包含特殊条目'.''..'

无论listdir()还是scandir(),都以任意顺序返回两者。

简而言之-预计不会出现订单。


话虽如此,您应该可以基于此部分在循环中操纵dirnames

  

topdown True时,呼叫者可以就地修改 dirnames 列表。   (也许使用delslice分配),而walk()仅会递归   进入名称保留在 dirnames 中的子目录;这可以是   用于修剪搜索,强加特定的访问顺序,甚至   通知walk()有关呼叫者创建或重命名的目录的信息   在再次恢复walk()之前。当 topdown 是时,修改 dirnames   False对步行的行为没有任何影响,因为自下而上   模式 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)