为什么要同时使用 os.path. abspath 和 os.path. realpath?

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

然而,我发现 os.path.abspath(__file__)os.path.realpath(__file__)产生相同的结果。 os.path.abspath(os.path.realpath(__file__))似乎有点多余。

人们用这个有什么原因吗?

75678 次浏览

os.path.realpath对那些支持它们的操作系统上的符号链接进行去防御。

os.path.abspath只是从提供从目录树根到指定文件(或 symlink)的完整路径的路径中删除类似于 ...的内容

例如,在 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 和 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'

用外行的话来说,如果您试图获取快捷文件的路径,则绝对路径给出 捷径位置中存在的文件的完整路径,而 realpath 给出文件的 原始位置路径。

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

Real path,os.path.realpath () ,提供所引用文件的完整路径。

例如:

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

除了已经提供的答案之外,在 Python 3.8中,os.path.realpath返回大写驱动器字母,而 os.path.abspath返回小写驱动器字母。

参见 这个问题