当前位置 主页 > 服务器问题 > Linux/apache问题 > 最大化 缩小

    使用Python解决Windows文件名非用反斜杠问题(python 小技巧)

    栏目:Linux/apache问题 时间:2019-11-05 00:58

     

    在编程过程中,我们往往会遇到一个小麻烦——微软 Windows 系统在文件夹名之间使用反斜杠字符,而几乎所有其它的计算机(操作系统)都使用正斜杠:

    Windows filenames: 
    C:\some_folder\some_file.txt 
    Most other operating systems: 
    /some_folder/some_file.txt 

    这是由于上世纪 80 年代早期计算机历史上的一个小意外。「MS-DOS」的第一版使用了正斜杠字符来指定命令行选项。当微软在「MS-DOS 2.0」中加入了对文件夹的支持时,正斜杠字符已经被使用了,所以他们采用了反斜杠作为替代。35 年后,我们仍然被受困于这种不一致性。

    如果你想让你的 Python 代码同时在 Windows 和 Mac/Linux 上工作,你就需要处理这种与平台相关的问题。幸运的是,Python 3 有一个名为「pathlib」的新模块,使得用户处理文件几乎没有任何困难。

    「pathlib」模块链接: https://docs.python.org/3/library/pathlib.html

    让我们快速浏览一下处理文件名路径的不同方法,看看「pathlib」如何能让你的生活变得更美好!

    错误的解决方案:手动构建文件路径

    假设你有一个数据文件夹,该文件夹包含你想要在你的 Python 程序中打开的文件:

     

    在 Python 中对其进行编码是「错误」的方式:

    data_folder = "source_data/text_files/" 
    file_to_open = data_folder + "raw_data.txt" 
    f = open(file_to_open) 
    print(f.read()) 

    请注意,由于我使用的是 Mac 系统,所以我使用了「Unix」风格的正斜杠对路径进行了硬编码。这也会让 Windows 的用户感到愤怒。

    从技术上讲,这段代码在 Windows 上仍然有效,因为 Python 有一个「黑客」(hack)技术:当你在 Windows 上调用「open()」函数时,它会识别这两种斜线。但即便如此,你也不应该依赖它。如果你在错误的操作系统上使用了错误类型的斜杠(尤其是在它们与外部程序或代码库交互时),并不是所有的 Python 库都会正常工作。

    Python 对混合斜杠类型的支持是一种只针对 Windows 的「黑客」技术,它反过来并不起作用。在 Mac 系统环境下,在代码中使用反斜杠会导致彻底失败:

    data_folder = "source_data\\text_files\\" 
    file_to_open = data_folder + "raw_data.txt" 
    f = open(file_to_open) 
    print(f.read()) 
    # On a Mac, this code will throw an exception: 
    # FileNotFoundError: [Errno 2] No such file or directory: 'source_data\\text_files\\raw_data.txt' 

    由于所有这些原因以及其他原因,使用硬编码的路径字符串编写代码,是一种会让其他程序员十分「嫌弃」的做法。一般来说,你应该尽量避免这么做。

    以前的解决方案:Python 的「os.path」模块

    Python 的「os.path」模块有很多工具来处理这类针对特定操作系统的文件系统问题。

    你可以使用「os.path.join()」为当前的操作系统构建一个使用正确类型斜杠的路径字符串:

    import os.path 
    data_folder = os.path.join("source_data", "text_files") 
    file_to_open = os.path.join(data_folder, "raw_data.txt") 
    f = open(file_to_open) 
    print(f.read()) 

    这段代码可以同时在「Windows」或「Mac」系统上完美运行。问题是它使用起来很麻烦。写出「os.path.join()」并将路径的每个部分作为独立的字符串传给该函数非常冗长,而且很不直观。

    由于「os.path」模块中的大多数函数使用起来很烦人,开发者们通常会「忘记」使用它们,即使他们知道这样做更好。这导致出现了很多跨平台的 Bug,也引起了用户的愤怒。