How to get absolute path of a pathlib.Path object?

血红的双手。 提交于 2020-07-17 03:05:46

问题


Making a path object with pathlib module like:

p = pathlib.Path('file.txt')

The p object will point to some file in the filesystem, since I can do for example p.read_text().

How can I get the absolute path of the p object in a string?

Appears that I can use for example os.path.abspath(p) to get the absolute path, but it awkward to use an os.path method, since I assume that pathlib should be a replacement for os.path.


回答1:


You're looking for the method .absolute, if my understanding is correct, who's documentation states:

>>> print(p.absolute.__doc__)
Return an absolute version of this path.  This function works
        even if the path doesn't point to anything.

        No normalization is done, i.e. all '.' and '..' will be kept along.
        Use resolve() to get the canonical path to a file.

With a test file on my system this returns:

>>> p = pathlib.Path('testfile')
>>> p.absolute()
PosixPath('/home/jim/testfile')

This method seems to be a new, and still, undocumented addition to Path and Path inheritting objects.

Created an issue to document this.




回答2:


Use resolve()

Simply use Path.resolve() like this:

    p = p.resolve()

This makes your path absolute and replaces all relative parts with absolute parts, and all symbolic links with physical paths. On case-insensitive file systems, it will also canonicalize the case (file.TXT becomes file.txt).

Avoid absolute()

You should not use absolute() because it's not documented, untested, and considered for removal. (See the discussion in the bug report created by @Jim Fasarakis Hilliard).

The difference

The difference between resolve and absolute is that absolute() does not replace the symbolically linked (symlink) parts of the path, and it never raises FileNotFoundError. It does not modify the case either.

If you want to avoid resolve() (e.g. you want to retain symlinks, casing, or relative parts) then use this instead:

    p = Path.cwd() / "file.txt"

Beware non-existing file on Windows

If the file does not exist, in Python 3.6+ on Windows, resolve() does not prepend the current working directory. See issue 38671.

Beware FileNotFoundError

On Python versions predating v3.6, resolve() does raise a FileNotFoundError if the path is not present on disk.

So if there's any risk to that, either check beforehand with p.exists() or try/catch the error.

    # check beforehand
    if p.exists():
        p = p.resolve()

    # or except afterward
    try:
        p = p.resolve()
    except FileNotFoundError:
        # deal with the missing file here
        pass

If you're dealing with a path that's not on disk, to begin with, and you're not on Python 3.6+, it's best to revert to os.path.abspath(str(p)).

From 3.6 on, resolve() only raises FileNotFoundError if you use the strict argument.

    # might raise FileNotFoundError
    p = p.resolve(strict=True)

But beware, using strict makes your code incompatible with Python versions predating 3.6 since those don't accept the strict argument.

The future

Follow issue 39090 to follow documentation changes related to absolute().




回答3:


If you simply want the path and do not want to check if the file exists, you can do

str(p)

as document in the Operations section.




回答4:


pathlib.Path.cwd() / p

This is recommended by CPython core developers as the "one obvious way".

p.resolve() does not return an absolute path for non-existing files on Windows at least.

p.absolute() is undocumented.



来源:https://stackoverflow.com/questions/42513056/how-to-get-absolute-path-of-a-pathlib-path-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!