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下會顯示
a\b\c

  • 即 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)
  • 會得到
    a\b\c
    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)
  • 會得到
    a\b\c
    a/b/c


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM