python - 为什么从 os.walk() 返回的 root 包含 / 作为目录分隔符而 os.sep(或 os.path.sep)在 Win10 上返回 \?
问题描述
为什么从os.walk()返回的根元素显示 / 作为目录分隔符但os.sep(或os.path.sep)在 Win10 上显示 \?
我只是想为文件夹中的一组文件创建完整路径,如下所示:
import os
base_folder = "c:/data/MA Maps"
for root, dirs, files in os.walk(base_folder):
for f in files:
if f.endswith(".png") and f.find("_N") != -1:
print(os.path.join(root, f))
print(os.path.sep)
这是我得到的输出:
c:/data/MA Maps\Map_of_Massachusetts_Nantucket_County.png
c:/data/MA Maps\Map_of_Massachusetts_Norfolk_County.png
\
我知道 python 的一些库函数(如 open())将与混合路径分隔符一起使用(至少在 Windows 上),但依赖于该 hack 确实不能在所有库中得到信任。看起来从os.walk()和os.path(.sep或.join())返回的项目应该根据所使用的操作系统产生一致的结果。谁能解释为什么会发生这种不一致?
PS - 我知道有一个更一致的库用于处理文件路径(以及许多其他文件操作) ,称为pathlib,它是在 python 3.4 中引入的,它似乎确实解决了所有这些问题。如果您的代码在 3.4 或更高版本中使用,是否最好使用pathlib方法来解决此问题?但是,如果您的代码是针对在 3.4 之前使用 python 的系统,那么解决这个问题的最佳方法是什么?
下面是pathlib的一个很好的基本解释:Python 3 Quick Tip: The easy way to deal with file paths on Windows, Mac and Linux
这是我使用pathlib的代码和结果:
import os
from pathlib import Path
# All of this should work properly for any OS. I'm running Win10.
# You can even mix up the separators used (i.e."c:\data/MA Maps") and pathlib still
# returns the consistent result given below.
base_folder = "c:/data/MA Maps"
for root, dirs, files in os.walk(base_folder):
# This changes the root path provided to one using the current operating systems
# path separator (/ for Win10).
root_folder = Path(root)
for f in files:
if f.endswith(".png") and f.find("_N") != -1:
# The / operator, when used with a pathlib object, just concatenates the
# the path segments together using the current operating system path separator.
print(root_folder / f)
c:\data\MA Maps\Map_of_Massachusetts_Nantucket_County.png
c:\data\MA Maps\Map_of_Massachusetts_Norfolk_County.png
这甚至可以更简洁地使用pathlib和列表理解来完成(每个使用的操作系统都正确处理所有路径分隔符):
from pathlib import Path
base_folder = "c:/data/MA Maps"
path = Path(base_folder)
files = [item for item in path.iterdir() if item.is_file() and
str(item).endswith(".png") and
(str(item).find("_N") != -1)]
for file in files:
print(file)
c:\data\MA Maps\Map_of_Massachusetts_Nantucket_County.png
c:\data\MA Maps\Map_of_Massachusetts_Norfolk_County.png
这是非常 Pythonic 的,至少我觉得它很容易阅读和理解。.iterdir() 真的很强大,它使处理文件和目录相当容易,并且以跨平台的方式。你怎么看?
解决方案
该函数始终从您传递给它的内容os.walk
中产生未更改的初始部分。dirpath
它不会尝试对分隔符本身进行规范化,它只是保留您给它的内容。它确实对路径的其余部分使用系统标准分隔符,因为它将每个子目录的名称与根目录结合在一起os.path.join
。您可以在 CPython 源代码库中查看该os.walk
函数的当前实现版本。
规范化输出中分隔符的一种选择是规范化传入的基本路径os.walk
,可能使用pathlib
. 如果您对初始路径进行规范化,则所有输出都应自动使用系统路径分隔符,因为它将是通过递归遍历保留的规范化路径,而不是非标准路径。这是您的第一个代码块的一个非常基本的转换,以规范化base_folder
using pathlib
,同时保留所有其余代码,简单。它是否比使用更多pathlib
功能的版本更好是我将留给您的判断电话。
import os
from pathlib import Path
base_folder = Path("c:/data/MA Maps") # this will be normalized when converted to a string
for root, dirs, files in os.walk(base_folder):
for f in files:
if f.endswith(".png") and f.find("_N") != -1:
print(os.path.join(root, f))
推荐阅读
- regex - 系统日志中“wp-admin”“wp-login”条目的正则表达式尝试在drupal站点上
- swift - Swift Firestore,“喜欢”功能不适用于表格视图单元格中的按钮
- linux - Bash:在双引号中打印变量导致'“”'
- javascript - 无法在节点 js 中使用 multer 获取文件(req.file 未定义)
- javascript - mmenujs:面板打开后采取行动
- tensorflow - 张量流变量值
- r - 在 R 中使用 XGBOOST 进行多类分类 - 测试数据的 100% 准确度 - 这是可以接受的吗?
- javascript - 使用react-router重定向后,如何从redux reducer初始化react组件状态
- android - 带有协程的嵌套回调函数
- workday-api - Workday中工人照片的更新时间可以被检索或用作过滤吗?