なぜos.path.abspathとos.path.realpathの両方を使用するのですか?


98

複数のオープンソースプロジェクトでos.path.abspath(os.path.realpath(__file__))、現在のファイルへの絶対パスを取得するために人々が実行するのを見てきました。

しかし、私はそれを見つけ、同じ結果os.path.abspath(__file__)os.path.realpath(__file__)生み出します。os.path.abspath(os.path.realpath(__file__))少し冗長なようです。

人々がそれを使用している理由はありますか?

回答:


66

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、それによって削除されます。


10
この回答は2つの関数の違いを説明していますが、の結果にコンポーネントrealpath()が含まれている可能性があることは事実ではなく、..両方を使用する理由の質問には実際には回答しません。jobradの答えはより正確です。
マイル

Python 3.7およびWindowsの場合、realpathはサブステッドドライブを認識しません。したがって、サブステッドドライブの場合、ソースフォルダーがc:\ MyFolder \ BlaのP:\とすると、realpathはc:\ MyFolder \ BlaではなくP:\を返します。「実際の」パスを取得する方法を知っている人はいますか?
トッテカールソン、

私にとって、abspath現在のディレクトリがシンボリックリンクである場合は、シンボリックリンクをたどります。この答えを見つけたのは、この動作を停止するためのstackoverflow.com/questions/54665065/…だけです。
ビクターセルジャンコ

107

あなたが述べたシナリオでは、os.path.realpath実際にos.path.abspath結果を返す前にを呼び出すので、realpathと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'

3
いいね。あなたのポイントを作るためにあなたの最後の例はそうあるべきですos.path.realpath(os.path.expanduser('~/subdir/../data'))
Arthur

3
変数がパスで使用されている場合は、os.path.expandvarsについても忘れないでください
Slavenskij

7

簡単に言えば、ショートカットファイルのパスを取得しようとしている場合、絶対パスはショートカットの場所にあるファイルの完全なパスを提供し、リアルパスはファイルの元の場所のパスを提供します。

絶対パス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"
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.