【问题标题】:Why would one use both, os.path.abspath and os.path.realpath?为什么要同时使用 os.path.abspath 和 os.path.realpath?
【发布时间】:2016-06-16 15:30:30
【问题描述】:

在多个开源项目中,我看到有人通过os.path.abspath(os.path.realpath(__file__)) 获取当前文件的绝对路径。

但是,我发现 os.path.abspath(__file__)os.path.realpath(__file__) 产生相同的结果。 os.path.abspath(os.path.realpath(__file__)) 好像有点多余。

人们使用它有什么原因吗?

【问题讨论】:

    标签: python


    【解决方案1】:

    对于您所述的场景,没有理由将 realpath 和 abspath 结合起来,因为os.path.realpath 在返回结果之前实际上调用了os.path.abspath(我检查了 Python 2.5 到 Python 3.6)。

    • os.path.abspath 返回绝对路径,但不解析其参数中的符号链接。
    • os.path.realpath 将首先解析路径中的所有符号链接,然后返回绝对路径。

    但是,如果您希望路径包含 ~abspath 或 realpath 都不会将 ~ 解析为用户的主目录,并且生成的路径将无效。您将需要使用os.path.expanduser 将其解析为用户的目录。

    为了便于解释,以下是我在 Windows 和 Linux、Python 3.4 和 Python 2.6 中验证的一些结果。当前目录(./)是我的主目录,如下所示:

    myhome
    |- data (symlink to /mnt/data)
    |- subdir (extra directory, for verbose explanation)
    
    # os.path.abspath returns the absolute path, but does NOT resolve symlinks in its argument
    os.path.abspath('./')
    '/home/myhome'
    os.path.abspath('./subdir/../data')
    '/home/myhome/data'
    
    
    # os.path.realpath will resolve symlinks AND return an absolute path from a relative path
    os.path.realpath('./')
    '/home/myhome'
    os.path.realpath('./subdir/../')
    '/home/myhome'
    os.path.realpath('./subdir/../data')
    '/mnt/data'
    
    # NEITHER abspath or realpath will resolve or remove ~.
    os.path.abspath('~/data')
    '/home/myhome/~/data'
    
    os.path.realpath('~/data')
    '/home/myhome/~/data'
    
    # And the returned path will be invalid
    os.path.exists(os.path.abspath('~/data'))
    False
    os.path.exists(os.path.realpath('~/data'))
    False
    
    # Use realpath + expanduser to resolve ~
    os.path.realpath(os.path.expanduser('~/subdir/../data'))
    '/mnt/data'
    

    【讨论】:

    • 不错。为了说明你的观点,你的最后一个例子应该是os.path.realpath(os.path.expanduser('~/subdir/../data'))
    • 如果在路径中使用变量,也不要忘记 os.path.expandvars
    【解决方案2】:

    os.path.realpath 在支持它们的操作系统上取消引用符号链接。

    os.path.abspath 只是从路径中删除 ... 之类的东西,给出从目录树根到命名文件(或符号链接)的完整路径

    例如,在 Ubuntu 上

    $ ls -l
    total 0
    -rw-rw-r-- 1 guest guest 0 Jun 16 08:36 a
    lrwxrwxrwx 1 guest guest 1 Jun 16 08:36 b -> a
    
    $ python
    Python 2.7.11 (default, Dec 15 2015, 16:46:19) 
    [GCC 4.8.4] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    
    >>> from os.path import abspath, realpath
    
    >>> abspath('b')
    '/home/guest/play/paths/b'
    
    >>> realpath('b')
    '/home/guest/play/paths/a'
    

    符号链接可以包含相对路径,因此需要同时使用两者。对realpath 的内部调用可能会返回包含嵌入.. 部分的路径,然后abspath 会删除该路径。

    【讨论】:

    • 虽然这个答案描述了这两个函数之间的区别,但 realpath() 的结果可能包含 .. 组件并不是真的,并且并没有真正回答你为什么要使用的问题两个都;乔拉德的回答更准确。
    • 对于 Python 3.7 和 windows,realpath 不理解 substed 驱动器因此对于 substed 驱动器说 P:\,具有源文件夹 c:\MyFolder\Bla,realpath 返回 P:\ 而不是 c: \MyFolder\Bla。有人知道如何获得“真实”路径吗?
    • 对我来说,如果当前目录是符号链接,abspath 仍然遵循符号链接。我只找到了这个答案stackoverflow.com/questions/54665065/… 来阻止这种行为。
    【解决方案3】:

    通俗地说,如果你想获取一个快捷方式文件的路径,绝对路径给出了快捷方式位置中文件的完整路径,而realpath给出了文件的原始位置路径。

    绝对路径,os.path.abspath(),给出文件的完整路径,该文件位于当前工作目录或您提到的目录中。

    真实路径,os.path.realpath(),给出了被引用文件的完整路径。

    例如:

    file = "shortcut_folder/filename"
    os.path.abspath(file) = "C:/Desktop/shortcut_folder/filename"
    os.path.realpath(file) = "D:/PyCharmProjects/Python1stClass/filename"
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-21
      • 1970-01-01
      • 2017-10-16
      • 1970-01-01
      • 1970-01-01
      • 2011-06-01
      • 1970-01-01
      • 2019-07-29
      相关资源
      最近更新 更多