• Python:os.path.join()产生的斜杠在Windows和Linux下的不同表现和解决方法


    Python:os.path.join()产生的斜杠在Windows和Linux下的不同表现和解决方法

    觉得有用的话,欢迎一起讨论相互学习~


    我的微博我的github我的B站

    原文链接
    https://www.polarxiong.com/archives/Python-os-path-join-产生的斜杠在Windows和Linux下的不同表现和解决方法.html#comments

    问题描述

    • 我一直以为Python是隔离了操作系统的差异,同样的function在不同操作系统下会有一致的结果,直到前几天临时切换到Windows下发现有些Python代码跑不出来,才发现如os.path.join()这样的方法在不同操作系统下的表现是不一致的。
    • 例如
    import os.path
    
    print(os.path.join('a', 'b', 'c'))
    

    在Linux/macOS下会显示
    a/b/c
    而在Windows下会显示
    ac

    • 即 os.path.join()在Linux/macOS下会以斜杠(/)分隔路径,而在Windows下则会以反斜杠()分隔路径。

    原因分析

    • 这种内置标准库方法的不一致从哪来的?官方文档实际上早就有明显的暗示了。
    • 在os.path的官方文档页面11.2. os.path — Common pathname manipulations — Python 3.7.0 documentation开始位置就提到源代码文件根据不同操作系统在三个不同文件中:
    • Source code: Lib/posixpath.py (for POSIX), Lib/ntpath.py (for Windows NT), and Lib/macpath.py (for Macintosh)
    • 可见在安装Python时就会根据不同操作系统,仅使用对应操作系统类别的os.path模块。如果顺着源码去看,就会发现os.path.join()在Linux下是以斜杠(/)作为分隔符的,而在Windows下则是以反斜杠()作为分隔符的。

    Mac的一些细节

    • 如果跟着看Macintosh操作系统对应的源码Lib/macpath.py的话,会很惊讶地发现Macintosh下不是以斜杠(/)也不是以反斜杠(),而是以冒号(:)作为分隔符的,是不是很震惊:我的mac怎么可能是以冒号(:)为分隔符的?!
    • 这其实是一个历史问题了,这里Lib/macpath.py仅应用到了2001发布的Mac OS X之前的Macintosh操作系统中,那时的Macintosh确实是用冒号(:)为分隔符的。而从2001年的Mac OS X开始,到2012年的OS X,再到2016年的macOS,都采用了遵循Unix的斜杠(/)分隔符,也就直接使用Linux的源码Lib/posixpath.py了。

    为什么Windows要使用反斜杠()

    • 为什么Windows不使用斜杠(/),而独树一帜使用反斜杠()呢,专门为了为难程序员?
    • 这其实也是个历史问题,归根到底还是因为Windows为了保持对DOS的兼容性,而DOS为什么要使用反斜杠()就说来话长了

    解决方法

    • 从上面的分析可以发现os.path.join()仅包含对应操作系统类型的实现,所以我们无法通过指定参数的形式生成诸如适用于Linux或Windows的路径,那么如何解决这一问题呢?这里以在Windows下生成Linux格式(斜杠(/)分隔符)路径为例来说明。

    通过str.replace()

    • 这是一种简单直接的方法,直接把Windows下os.path.join()生成的反斜杠()全部替换为斜杠(/),如:
    import os.path
    
    result = os.path.join('a', 'b', 'c')
    print(result)
    
    result = result.replace('\', '/')
    print(result)
    
    • 会得到
      ac
      a/b/c

    通过pathlib.PurePath.as_posix()

    • 从Python 3.4开始可以通过pathlib.PurePath.as_posix()来生成斜杠(/)格式的路径,其实其实现原理和str.replace()并没有太大区别。例如:
    import os.path
    from pathlib import Path
    
    result = os.path.join('a', 'b', 'c')
    print(result)
    
    result = Path(result).as_posix()
    print(result)
    
    • 会得到
      ac
      a/b/c
  • 相关阅读:
    Linux安装步骤
    Python邮件发送
    拉链表
    Hive
    Shell笔记
    Hadoop入门
    Thinkphp手把手练习
    Shell学习日记
    Linux安装mysql数据库
    Oracle集合操作
  • 原文地址:https://www.cnblogs.com/cloud-ken/p/12666916.html
Copyright © 2020-2023  润新知