有没有一种方便的方法将文件 uri 映射到 os.path?

发布于 2024-11-06 22:32:42 字数 84 浏览 0 评论 0原文

我无法控制的子系统坚持以 uri 的形式提供文件系统路径。是否有一个 python 模块/函数可以以独立于平台的方式将此路径转换为文件系统所需的适当形式?

A subsystem which I have no control over insists on providing filesystem paths in the form of a uri. Is there a python module/function which can convert this path into the appropriate form expected by the filesystem in a platform independent manner?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

如梦初醒的夏天 2024-11-13 22:32:42

@Jakob Bowyer 的解决方案不会将 URL 编码字符 转换为常规 UTF-8 字符。为此,您需要使用 urllib.parse.unquote< /代码>

>>> from urllib.parse import unquote, urlparse
>>> unquote(urlparse('file:///home/user/some%20file.txt').path)
'/home/user/some file.txt'

The solution from @Jakob Bowyer doesn't convert URL encoded characters to regular UTF-8 characters. For that you need to use urllib.parse.unquote.

>>> from urllib.parse import unquote, urlparse
>>> unquote(urlparse('file:///home/user/some%20file.txt').path)
'/home/user/some file.txt'
祁梦 2024-11-13 22:32:42

使用 urllib.parse.urlparse 从 URI 获取路径:

import os
from urllib.parse import urlparse
p = urlparse('file://C:/test/doc.txt')
final_path = os.path.abspath(os.path.join(p.netloc, p.path))

Use urllib.parse.urlparse to get the path from the URI:

import os
from urllib.parse import urlparse
p = urlparse('file://C:/test/doc.txt')
final_path = os.path.abspath(os.path.join(p.netloc, p.path))
挽手叙旧 2024-11-13 22:32:42

到目前为止,在所有答案中,我发现没有一个能够捕获边缘情况、不需要分支、2/3 兼容、跨平台。

简而言之,仅使用内置函数就可以完成这项工作:(

try:
    from urllib.parse import urlparse, unquote
    from urllib.request import url2pathname
except ImportError:
    # backwards compatability
    from urlparse import urlparse
    from urllib import unquote, url2pathname


def uri_to_path(uri):
    parsed = urlparse(uri)
    host = "{0}{0}{mnt}{0}".format(os.path.sep, mnt=parsed.netloc)
    return os.path.normpath(
        os.path.join(host, url2pathname(unquote(parsed.path)))
    )

我发现)棘手的一点是在 Windows 中使用指定主机的路径工作时。这在 Windows 之外不是问题:*NIX 中的网络位置只能在安装到文件系统根目录后通过路径访问。

来自维基百科
文件 URI 采用 file://host/path 的形式,其中 host 是可访问路径的系统的完全限定域名 [...]。如果省略主机,则将其视为“localhost”。

考虑到这一点,我制定了一条规则,即在将路径传递给 os.path.abspath 之前,始终使用 urlparse 提供的 netloc 为路径添加前缀。 code>,这是必要的,因为它删除了任何产生的冗余斜杠(os.path.normpath,它也声称修复了斜杠,可以稍微超过- 热衷于 Windows,因此使用 abspath)。

转换中的另一个关键部分是使用 unquote 转义/解码 URL 百分比编码,否则您的文件系统将无法理解该编码。同样,这在 Windows 上可能是一个更大的问题,它允许在路径中使用诸如 $空格 之类的内容,这些内容将在文件 URI 中进行编码。

对于演示:

import os
from pathlib import Path   # This demo requires pip install for Python < 3.4
import sys
try:
    from urllib.parse import urlparse, unquote
    from urllib.request import url2pathname
except ImportError:  # backwards compatability:
    from urlparse import urlparse
    from urllib import unquote, url2pathname

DIVIDER = "-" * 30

if sys.platform == "win32":  # WINDOWS
    filepaths = [
        r"C:\Python27\Scripts\pip.exe",
        r"C:\yikes\paths with spaces.txt",
        r"\\localhost\c$\WINDOWS\clock.avi",
        r"\\networkstorage\homes\rdekleer",
    ]
else:  # *NIX
    filepaths = [
        os.path.expanduser("~/.profile"),
        "/usr/share/python3/py3versions.py",
    ]

for path in filepaths:
    uri = Path(path).as_uri()
    parsed = urlparse(uri)
    host = "{0}{0}{mnt}{0}".format(os.path.sep, mnt=parsed.netloc)
    normpath = os.path.normpath(
        os.path.join(host, url2pathname(unquote(parsed.path)))
    )
    absolutized = os.path.abspath(
        os.path.join(host, url2pathname(unquote(parsed.path)))
    )
    result = ("{DIVIDER}"
              "\norig path:       \t{path}"
              "\nconverted to URI:\t{uri}"
              "\nrebuilt normpath:\t{normpath}"
              "\nrebuilt abspath:\t{absolutized}").format(**locals())
    print(result)
    assert path == absolutized

结果 (WINDOWS):

------------------------------
orig path:              C:\Python27\Scripts\pip.exe
converted to URI:       file:///C:/Python27/Scripts/pip.exe
rebuilt normpath:       C:\Python27\Scripts\pip.exe
rebuilt abspath:        C:\Python27\Scripts\pip.exe
------------------------------
orig path:              C:\yikes\paths with spaces.txt
converted to URI:       file:///C:/yikes/paths%20with%20spaces.txt
rebuilt normpath:       C:\yikes\paths with spaces.txt
rebuilt abspath:        C:\yikes\paths with spaces.txt
------------------------------
orig path:              \\localhost\c$\WINDOWS\clock.avi
converted to URI:       file://localhost/c%24/WINDOWS/clock.avi
rebuilt normpath:       \localhost\c$\WINDOWS\clock.avi
rebuilt abspath:        \\localhost\c$\WINDOWS\clock.avi
------------------------------
orig path:              \\networkstorage\homes\rdekleer
converted to URI:       file://networkstorage/homes/rdekleer
rebuilt normpath:       \networkstorage\homes\rdekleer
rebuilt abspath:        \\networkstorage\homes\rdekleer

结果 (*NIX):

------------------------------
orig path:              /home/rdekleer/.profile
converted to URI:       file:///home/rdekleer/.profile
rebuilt normpath:       /home/rdekleer/.profile
rebuilt abspath:        /home/rdekleer/.profile
------------------------------
orig path:              /usr/share/python3/py3versions.py
converted to URI:       file:///usr/share/python3/py3versions.py
rebuilt normpath:       /usr/share/python3/py3versions.py
rebuilt abspath:        /usr/share/python3/py3versions.py

Of all the answers so far, I found none that catch edge cases, doesn't require branching, are both 2/3 compatible, and cross-platform.

In short, this does the job, using only builtins:

try:
    from urllib.parse import urlparse, unquote
    from urllib.request import url2pathname
except ImportError:
    # backwards compatability
    from urlparse import urlparse
    from urllib import unquote, url2pathname


def uri_to_path(uri):
    parsed = urlparse(uri)
    host = "{0}{0}{mnt}{0}".format(os.path.sep, mnt=parsed.netloc)
    return os.path.normpath(
        os.path.join(host, url2pathname(unquote(parsed.path)))
    )

The tricky bit (I found) was when working in Windows with paths specifying a host. This is a non-issue outside of Windows: network locations in *NIX can only be reached via paths after being mounted to the root of the filesystem.

From Wikipedia:
A file URI takes the form of file://host/path , where host is the fully qualified domain name of the system on which the path is accessible [...]. If host is omitted, it is taken to be "localhost".

With that in mind, I make it a rule to ALWAYS prefix the path with the netloc provided by urlparse, before passing it to os.path.abspath, which is necessary as it removes any resulting redundant slashes (os.path.normpath, which also claims to fix the slashes, can get a little over-zealous in Windows, hence the use of abspath).

The other crucial component in the conversion is using unquote to escape/decode the URL percent-encoding, which your filesystem won't otherwise understand. Again, this might be a bigger issue on Windows, which allows things like $ and spaces in paths, which will have been encoded in the file URI.

For a demo:

import os
from pathlib import Path   # This demo requires pip install for Python < 3.4
import sys
try:
    from urllib.parse import urlparse, unquote
    from urllib.request import url2pathname
except ImportError:  # backwards compatability:
    from urlparse import urlparse
    from urllib import unquote, url2pathname

DIVIDER = "-" * 30

if sys.platform == "win32":  # WINDOWS
    filepaths = [
        r"C:\Python27\Scripts\pip.exe",
        r"C:\yikes\paths with spaces.txt",
        r"\\localhost\c$\WINDOWS\clock.avi",
        r"\\networkstorage\homes\rdekleer",
    ]
else:  # *NIX
    filepaths = [
        os.path.expanduser("~/.profile"),
        "/usr/share/python3/py3versions.py",
    ]

for path in filepaths:
    uri = Path(path).as_uri()
    parsed = urlparse(uri)
    host = "{0}{0}{mnt}{0}".format(os.path.sep, mnt=parsed.netloc)
    normpath = os.path.normpath(
        os.path.join(host, url2pathname(unquote(parsed.path)))
    )
    absolutized = os.path.abspath(
        os.path.join(host, url2pathname(unquote(parsed.path)))
    )
    result = ("{DIVIDER}"
              "\norig path:       \t{path}"
              "\nconverted to URI:\t{uri}"
              "\nrebuilt normpath:\t{normpath}"
              "\nrebuilt abspath:\t{absolutized}").format(**locals())
    print(result)
    assert path == absolutized

Results (WINDOWS):

------------------------------
orig path:              C:\Python27\Scripts\pip.exe
converted to URI:       file:///C:/Python27/Scripts/pip.exe
rebuilt normpath:       C:\Python27\Scripts\pip.exe
rebuilt abspath:        C:\Python27\Scripts\pip.exe
------------------------------
orig path:              C:\yikes\paths with spaces.txt
converted to URI:       file:///C:/yikes/paths%20with%20spaces.txt
rebuilt normpath:       C:\yikes\paths with spaces.txt
rebuilt abspath:        C:\yikes\paths with spaces.txt
------------------------------
orig path:              \\localhost\c$\WINDOWS\clock.avi
converted to URI:       file://localhost/c%24/WINDOWS/clock.avi
rebuilt normpath:       \localhost\c$\WINDOWS\clock.avi
rebuilt abspath:        \\localhost\c$\WINDOWS\clock.avi
------------------------------
orig path:              \\networkstorage\homes\rdekleer
converted to URI:       file://networkstorage/homes/rdekleer
rebuilt normpath:       \networkstorage\homes\rdekleer
rebuilt abspath:        \\networkstorage\homes\rdekleer

Results (*NIX):

------------------------------
orig path:              /home/rdekleer/.profile
converted to URI:       file:///home/rdekleer/.profile
rebuilt normpath:       /home/rdekleer/.profile
rebuilt abspath:        /home/rdekleer/.profile
------------------------------
orig path:              /usr/share/python3/py3versions.py
converted to URI:       file:///usr/share/python3/py3versions.py
rebuilt normpath:       /usr/share/python3/py3versions.py
rebuilt abspath:        /usr/share/python3/py3versions.py
a√萤火虫的光℡ 2024-11-13 22:32:42

要使用 python 将文件 uri 转换为路径(具体到 3,如果有人真的想要的话,我可以制作 python 2):

  1. 使用 urllib.parse.urlparse 解析 uri

  2. 使用 urllib.parse.unquote 取消引用已解析 uri 的路径部分

  3. then ...

...如果路径是 Windows 路径并以 / 开头:去掉不带引号的路径组件的第一个字符(file:///C:/some/file.txt 的路径组件是 /C:/some/file.txt ,它不被 pathlib.PureWindowsPathC:\some\file.txt >)

b.否则,只需按原样使用未加引号的路径组件。

下面是执行此操作的函数:

import urllib
import pathlib

def file_uri_to_path(file_uri, path_class=pathlib.PurePath):
    """
    This function returns a pathlib.PurePath object for the supplied file URI.

    :param str file_uri: The file URI ...
    :param class path_class: The type of path in the file_uri. By default it uses
        the system specific path pathlib.PurePath, to force a specific type of path
        pass pathlib.PureWindowsPath or pathlib.PurePosixPath
    :returns: the pathlib.PurePath object
    :rtype: pathlib.PurePath
    """
    windows_path = isinstance(path_class(),pathlib.PureWindowsPath)
    file_uri_parsed = urllib.parse.urlparse(file_uri)
    file_uri_path_unquoted = urllib.parse.unquote(file_uri_parsed.path)
    if windows_path and file_uri_path_unquoted.startswith("/"):
        result = path_class(file_uri_path_unquoted[1:])
    else:
        result = path_class(file_uri_path_unquoted)
    if result.is_absolute() == False:
        raise ValueError("Invalid file uri {} : resulting path {} not absolute".format(
            file_uri, result))
    return result

使用示例(在 Linux 上运行):

>>> file_uri_to_path("file:///etc/hosts")
PurePosixPath('/etc/hosts')

>>> file_uri_to_path("file:///etc/hosts", pathlib.PurePosixPath)
PurePosixPath('/etc/hosts')

>>> file_uri_to_path("file:///C:/Program Files/Steam/", pathlib.PureWindowsPath)
PureWindowsPath('C:/Program Files/Steam')

>>> file_uri_to_path("file:/proc/cpuinfo", pathlib.PurePosixPath)
PurePosixPath('/proc/cpuinfo')

>>> file_uri_to_path("file:c:/system32/etc/hosts", pathlib.PureWindowsPath)
PureWindowsPath('c:/system32/etc/hosts')

该函数适用于 Windows 和 posix 文件 URI,并且它将处理没有权限部分的文件 URI。然而,它不会验证 URI 的权限,因此不会遵守:

IETF RFC 8089:“文件”URI 方案 / 2. 语法

“主机”是系统的完全限定域名
该文件是可访问的。这允许另一个系统上的客户端
知道它无法访问文件系统,或者可能需要
使用其他本地机制来访问文件。

该功能的验证(pytest):

import os
import pytest

def validate(file_uri, expected_windows_path, expected_posix_path):
    if expected_windows_path is not None:
        expected_windows_path_object = pathlib.PureWindowsPath(expected_windows_path)
    if expected_posix_path is not None:
        expected_posix_path_object = pathlib.PurePosixPath(expected_posix_path)

    if expected_windows_path is not None:
        if os.name == "nt":
            assert file_uri_to_path(file_uri) == expected_windows_path_object
        assert file_uri_to_path(file_uri, pathlib.PureWindowsPath) == expected_windows_path_object

    if expected_posix_path is not None:
        if os.name != "nt":
            assert file_uri_to_path(file_uri) == expected_posix_path_object
        assert file_uri_to_path(file_uri, pathlib.PurePosixPath) == expected_posix_path_object


def test_some_paths():
    validate(pathlib.PureWindowsPath(r"C:\Windows\System32\Drivers\etc\hosts").as_uri(),
        expected_windows_path=r"C:\Windows\System32\Drivers\etc\hosts",
        expected_posix_path=r"/C:/Windows/System32/Drivers/etc/hosts")

    validate(pathlib.PurePosixPath(r"/C:/Windows/System32/Drivers/etc/hosts").as_uri(),
        expected_windows_path=r"C:\Windows\System32\Drivers\etc\hosts",
        expected_posix_path=r"/C:/Windows/System32/Drivers/etc/hosts")

    validate(pathlib.PureWindowsPath(r"C:\some dir\some file").as_uri(),
        expected_windows_path=r"C:\some dir\some file",
        expected_posix_path=r"/C:/some dir/some file")

    validate(pathlib.PurePosixPath(r"/C:/some dir/some file").as_uri(),
        expected_windows_path=r"C:\some dir\some file",
        expected_posix_path=r"/C:/some dir/some file")

def test_invalid_url():
    with pytest.raises(ValueError) as excinfo:
        validate(r"file://C:/test/doc.txt",
            expected_windows_path=r"test\doc.txt",
            expected_posix_path=r"/test/doc.txt")
        assert "is not absolute" in str(excinfo.value)

def test_escaped():
    validate(r"file:///home/user/some%20file.txt",
        expected_windows_path=None,
        expected_posix_path=r"/home/user/some file.txt")
    validate(r"file:///C:/some%20dir/some%20file.txt",
        expected_windows_path="C:\some dir\some file.txt",
        expected_posix_path=r"/C:/some dir/some file.txt")

def test_no_authority():
    validate(r"file:c:/path/to/file",
        expected_windows_path=r"c:\path\to\file",
        expected_posix_path=None)
    validate(r"file:/path/to/file",
        expected_windows_path=None,
        expected_posix_path=r"/path/to/file")

此贡献已根据 Zero- 获得许可(除了可能适用的任何其他许可证之外)条款 BSD 许可证 (0BSD) 许可证

允许为任何目的使用、复制、修改和/或分发本软件
特此授予有或无费用的目的。

该软件按“原样”提供,作者不承担任何保证
关于本软件,包括所有默示保证
适销性和适用性。在任何情况下,作者均不承担任何责任
任何特殊、直接、间接或后果性损害或任何损害
无论是由于使用、数据或利润损失而导致的,无论是在
合同行为、疏忽或其他侵权行为,引起的
或与本软件的使用或性能有关。


公共领域

在法律允许的范围内,Iwan Aucamp 已放弃此 stackexchange 贡献的所有版权以及相关或邻接权。本作品出版自:挪威。

To convert a file uri to a path with python (specific to 3, I can make for python 2 if someone really wants it):

  1. Parse the uri with urllib.parse.urlparse

  2. Unquote the path component of the parsed uri with urllib.parse.unquote

  3. then ...

a. If path is a windows path and starts with /: strip the first character of unquoted path component (path component of file:///C:/some/file.txt is /C:/some/file.txt which is not interpreted to be equivalent to C:\some\file.txt by pathlib.PureWindowsPath)

b. Otherwise just use the unquoted path component as is.

Here is a function that does this:

import urllib
import pathlib

def file_uri_to_path(file_uri, path_class=pathlib.PurePath):
    """
    This function returns a pathlib.PurePath object for the supplied file URI.

    :param str file_uri: The file URI ...
    :param class path_class: The type of path in the file_uri. By default it uses
        the system specific path pathlib.PurePath, to force a specific type of path
        pass pathlib.PureWindowsPath or pathlib.PurePosixPath
    :returns: the pathlib.PurePath object
    :rtype: pathlib.PurePath
    """
    windows_path = isinstance(path_class(),pathlib.PureWindowsPath)
    file_uri_parsed = urllib.parse.urlparse(file_uri)
    file_uri_path_unquoted = urllib.parse.unquote(file_uri_parsed.path)
    if windows_path and file_uri_path_unquoted.startswith("/"):
        result = path_class(file_uri_path_unquoted[1:])
    else:
        result = path_class(file_uri_path_unquoted)
    if result.is_absolute() == False:
        raise ValueError("Invalid file uri {} : resulting path {} not absolute".format(
            file_uri, result))
    return result

Usage examples (ran on linux):

>>> file_uri_to_path("file:///etc/hosts")
PurePosixPath('/etc/hosts')

>>> file_uri_to_path("file:///etc/hosts", pathlib.PurePosixPath)
PurePosixPath('/etc/hosts')

>>> file_uri_to_path("file:///C:/Program Files/Steam/", pathlib.PureWindowsPath)
PureWindowsPath('C:/Program Files/Steam')

>>> file_uri_to_path("file:/proc/cpuinfo", pathlib.PurePosixPath)
PurePosixPath('/proc/cpuinfo')

>>> file_uri_to_path("file:c:/system32/etc/hosts", pathlib.PureWindowsPath)
PureWindowsPath('c:/system32/etc/hosts')

This function works for windows and posix file URIs and it will handle file URIs without an authority section. It will however NOT do validation of the URI's authority so this will not be honoured:

IETF RFC 8089: The "file" URI Scheme / 2. Syntax

The "host" is the fully qualified domain name of the system on which
the file is accessible. This allows a client on another system to
know that it cannot access the file system, or perhaps that it needs
to use some other local mechanism to access the file.

Validation (pytest) for the function:

import os
import pytest

def validate(file_uri, expected_windows_path, expected_posix_path):
    if expected_windows_path is not None:
        expected_windows_path_object = pathlib.PureWindowsPath(expected_windows_path)
    if expected_posix_path is not None:
        expected_posix_path_object = pathlib.PurePosixPath(expected_posix_path)

    if expected_windows_path is not None:
        if os.name == "nt":
            assert file_uri_to_path(file_uri) == expected_windows_path_object
        assert file_uri_to_path(file_uri, pathlib.PureWindowsPath) == expected_windows_path_object

    if expected_posix_path is not None:
        if os.name != "nt":
            assert file_uri_to_path(file_uri) == expected_posix_path_object
        assert file_uri_to_path(file_uri, pathlib.PurePosixPath) == expected_posix_path_object


def test_some_paths():
    validate(pathlib.PureWindowsPath(r"C:\Windows\System32\Drivers\etc\hosts").as_uri(),
        expected_windows_path=r"C:\Windows\System32\Drivers\etc\hosts",
        expected_posix_path=r"/C:/Windows/System32/Drivers/etc/hosts")

    validate(pathlib.PurePosixPath(r"/C:/Windows/System32/Drivers/etc/hosts").as_uri(),
        expected_windows_path=r"C:\Windows\System32\Drivers\etc\hosts",
        expected_posix_path=r"/C:/Windows/System32/Drivers/etc/hosts")

    validate(pathlib.PureWindowsPath(r"C:\some dir\some file").as_uri(),
        expected_windows_path=r"C:\some dir\some file",
        expected_posix_path=r"/C:/some dir/some file")

    validate(pathlib.PurePosixPath(r"/C:/some dir/some file").as_uri(),
        expected_windows_path=r"C:\some dir\some file",
        expected_posix_path=r"/C:/some dir/some file")

def test_invalid_url():
    with pytest.raises(ValueError) as excinfo:
        validate(r"file://C:/test/doc.txt",
            expected_windows_path=r"test\doc.txt",
            expected_posix_path=r"/test/doc.txt")
        assert "is not absolute" in str(excinfo.value)

def test_escaped():
    validate(r"file:///home/user/some%20file.txt",
        expected_windows_path=None,
        expected_posix_path=r"/home/user/some file.txt")
    validate(r"file:///C:/some%20dir/some%20file.txt",
        expected_windows_path="C:\some dir\some file.txt",
        expected_posix_path=r"/C:/some dir/some file.txt")

def test_no_authority():
    validate(r"file:c:/path/to/file",
        expected_windows_path=r"c:\path\to\file",
        expected_posix_path=None)
    validate(r"file:/path/to/file",
        expected_windows_path=None,
        expected_posix_path=r"/path/to/file")

This contribution is licensed (in addition to any other licenses which may apply) under the Zero-Clause BSD License (0BSD) license

Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.


Public Domain

To the extent possible under law, Iwan Aucamp has waived all copyright and related or neighboring rights to this stackexchange contribution. This work is published from: Norway.

予囚 2024-11-13 22:32:42

从 python 3.13 开始,您可以使用 pathlib。 Path.from_uri() 方法,一个新的构造函数,用于从“文件”URI (file://) 创建 pathlib.Path 对象。

例如:

>>> p = Path.from_uri('file:////server/share')
WindowsPath('//server/share')
>>> p = Path.from_uri('file://///server/share')
WindowsPath('//server/share')
>>> p = Path.from_uri('file:c:/windows')
WindowsPath('c:/windows')
>>> p = Path.from_uri('file:/c|/windows')
WindowsPath('c:/windows')

Starting from python 3.13, you can use the pathlib.Path.from_uri() method, a new constructor to create a pathlib.Path object from a ‘file’ URI (file://).

For example:

>>> p = Path.from_uri('file:////server/share')
WindowsPath('//server/share')
>>> p = Path.from_uri('file://///server/share')
WindowsPath('//server/share')
>>> p = Path.from_uri('file:c:/windows')
WindowsPath('c:/windows')
>>> p = Path.from_uri('file:/c|/windows')
WindowsPath('c:/windows')
送君千里 2024-11-13 22:32:42

@colton7909 的解决方案大部分是正确的,并帮助我得到了这个答案,但在 Python 3 中存在一些导入错误。我认为这是处理 'file://' URL 的一部分,而不是简单地删除前 7 个字符。所以我觉得这是使用标准库执行此操作的最惯用的方法:

import urllib.parse
url_data = urllib.parse.urlparse('file:///home/user/some%20file.txt')
path = urllib.parse.unquote(url_data.path)

此示例应生成字符串 '/home/user/some file.txt'

The solution from @colton7909 is mostly correct and helped me get to this answer, but has some import errors with Python 3. That and I think this is a better way to deal with the 'file://' part of the URL than simply chopping off the first 7 characters. So I feel this is the most idiomatic way to do this using the standard library:

import urllib.parse
url_data = urllib.parse.urlparse('file:///home/user/some%20file.txt')
path = urllib.parse.unquote(url_data.path)

This example should produce the string '/home/user/some file.txt'

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文