簡體   English   中英

在 Windows 上使用 os.path.join 混合斜線

[英]mixed slashes with os.path.join on windows

我傾向於只對路徑('/')使用正斜杠,python 在 Windows 上也對它很滿意。 在 os.path.join 的描述中,它說如果你想跨平台,這是正確的方法。 但是當我使用它時,我得到了混合斜線:

import os

a = 'c:/'
b = 'myFirstDirectory/'
c = 'mySecondDirectory'
d = 'myThirdDirectory'
e = 'myExecutable.exe'


print os.path.join(a, b, c, d, e)

# Result:
c:/myFirstDirectory/mySecondDirectory\myThirdDirectory\myExecutable.exe

這樣對嗎? 我應該事后檢查並糾正它還是有更好的方法?

謝謝

編輯:我在詢問路徑時也會得到混合斜線

import sys
for item in sys.path:
    print item

# Result:
C:\Program Files\Autodesk\Maya2013.5\bin
C:\Program Files\Autodesk\Maya2013.5\mentalray\scripts\AETemplates
C:\Program Files\Autodesk\Maya2013.5\Python
C:\Program Files\Autodesk\Maya2013.5\Python\lib\site-packages
C:\Program Files\Autodesk\Maya2013.5\bin\python26.zip\lib-tk
C:/Users/nookie/Documents/maya/2013.5-x64/prefs/scripts
C:/Users/nookie/Documents/maya/2013.5-x64/scripts
C:/Users/nookie/Documents/maya/scripts
C:\Program Files\Nuke7.0v4\lib\site-packages
C:\Program Files\Nuke7.0v4/plugins/modules

您可以在path.join() .replace()之后使用.replace()以確保斜線正確:

# .replace() all backslashes with forwardslashes
print os.path.join(a, b, c, d, e).replace("\\","/")

這給出了輸出:

c:/myFirstDirectory/mySecondDirectory/myThirdDirectory/myExecutable.exe

正如@sharpcloud 所建議的那樣,最好從輸入字符串中刪除斜杠,但這是一種替代方法。

您現在自己提供一些斜線並讓os.path.join選擇其他斜線。 最好讓python選擇所有這些或自己提供它們。 Python 對路徑的后半部分使用反斜杠,因為反斜杠是 Windows 上的默認值。

import os

a = 'c:' # removed slash
b = 'myFirstDirectory' # removed slash
c = 'mySecondDirectory'
d = 'myThirdDirectory'
e = 'myExecutable.exe'

print os.path.join(a + os.sep, b, c, d, e)

我還沒有測試過這個,但我希望這會有所幫助。 更常見的是有一個基本路徑並且只需要加入一個其他元素,主要是文件。

順便一提; 您可以使用os.sep來獲得運行 python 的操作系統的最佳分隔符。

編輯:正如 dash-tom-bang 所述,顯然對於 Windows,您確實需要為路徑的根包含一個分隔符。 否則,您將創建一個相對路徑而不是絕對路徑。

嘗試使用 abspath(使用 python 3)

import os

a = 'c:/'
b = 'myFirstDirectory/'
c = 'mySecondDirectory'
d = 'myThirdDirectory'
e = 'myExecutable.exe'


print(os.path.abspath(os.path.join(a, b, c, d, e)))

輸出:

c:\\myFirstDirectory\\mySecondDirectory\\myThirdDirectory\\myExecutable.exe

進程以退出代碼 0 結束

根據評論編輯: path = os.path.normpath(path)

我之前的答案缺乏處理轉義字符的能力,因此不應使用

  • 首先,將路徑轉換為文件夾和文件名的數組。
  • 其次,使用正確的符號將它們粘在一起。

     import os path = 'c:\\www\\app\\my/folder/file.php' # split the path to parts by either slash symbol: path = re.compile(r"[\\/]").split(path) # join the path using the correct slash symbol: path = os.path.join(*path)

如果出於任何原因您需要自己提供路徑並且您使用了 python 3.4 以上的任何內容,則可以使用pathlib

from pathlib import Path, PurePosixPath

a = PurePosixPath('c:/')
b = PurePosixPath('myFirstDirectory/')
c = 'mySecondDirectory'
d = 'myThirdDirectory'
e = 'myExecutable.exe'

print(a / b / c / d / e)

# Result
c:/myFirstDirectory/mySecondDirectory/myThirdDirectory/myExecutable.exe

當我需要用戶提供資產目錄的位置並且我的代碼正在使用 Windows 路徑字符串查找時,我使用了它

In [1]: from pathlib import Path, PureWindowsPath
In [2]: USER_ASSETS_DIR = Path('/asset/dir') # user provides this form environment variable
In [3]: SPECIFIC_ASSET = PureWindowsPath('some\\asset')
In [4]: USER_ASSETS_DIR / SPECIFIC_ASSET

Out[4]: PosixPath('/asset/dir/some/asset')

os為您添加斜杠並確保不要重復斜杠,因此請在字符串中省略它們

import os

# Don't add your own slashes
a = 'C:'
b = 'myFirstDirectory' 
c = 'mySecondDirectory'
d = 'myThirdDirectory'
e = 'myExecutable.exe'

print os.path.join(a, b, c, d, e)
C:\myFirstDirectory\mySecondDirectory\myThirdDirectory\myExecutable.exe

額外的:

我不確定為什么你的 sys 路徑中混合了斜杠(你是否使用了 linux os 添加了一些文件夾?)但請嘗試檢查

print os.path.isdir(os.path.join('C:','Users','nookie'))

如果這是Trueos適用於您的混合斜杠。

無論哪種方式,我都會避免將目錄名稱硬編碼到您的程序中。 您的sys.path for 循環是提取這些目錄的安全方法。 然后,您可以使用一些字符串方法或正則表達式來選擇所需的文件夾。

Postgres 命令客戶端psql即使在 Windows 上也不接受反斜杠:

>psql -U user -h 111.111.111.111 -d mydb
psql (12.2, server 12.5 . . .
. . .
mydb=> \i C:\my\path\myscript.sql
C:: Permission denied

所以需要在從Python 3.8.6執行時修復它。 不想訴諸幼稚的字符串替換並使用現有功能:

script_path = Path(script_dir).resolve()
input_sql = f'\\i {script_path.joinpath("myscript.sql").as_posix()}\n'

但在引擎蓋下它有:

# ...\Programs\Python\Python38\Lib\pathlib.py
    def as_posix(self):
        """Return the string representation of the path with forward (/)
        slashes."""
        f = self._flavour
        return str(self).replace(f.sep, '/')

你也可以這樣做:

import re

a = 'c:/'
b = 'myFirstDirectory/'
c = 'mySecondDirectory'
d = 'myThirdDirectory'
e = 'myExecutable.exe'

joined = os.path.join(a, b, c, d, e)
formatted = re.sub(r'/|\\', re.escape(os.sep), joined)

這會將您所有可能混合的斜杠轉換為符合操作系統的斜杠。

我知道這是一個古老的話題,但我無法抗拒。 :)

我這樣做的方法相當簡單:從斜杠中rstrip所有路徑,無論數量和正確性如何,使用正確的分隔符將這些路徑添加回去。

import os

def join_path_regardless_of_separators(*paths):
    return os.path.sep.join(path.rstrip(r"\/") for path in paths)
 
a = 'c:/'
b = 'myFirstDirectory/'
c = 'mySecondDirectory'
d = 'myThirdDirectory\\\\\\/'
e = 'myExecutable.exe'
join_path_regardless_of_separators(a, b, c, d, e)
>>> 'c:\\myFirstDirectory\\mySecondDirectory\\myThirdDirectory\\myExecutable.exe'

使用它的另一種方法,以獲得相同的結果:

join_path_regardless_of_separators(*"""c:////\\\\
                                       myFirstDirectory/
                                       mySecondDirectory\\\\
                                       myThirdDirectory/////
                                       myExecutable.exe
                                    """.split())

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM