Neden hem os.path.abspath hem de os.path.realpath kullanılsın?


102

Birden çok açık kaynaklı projede, insanların os.path.abspath(os.path.realpath(__file__))mevcut dosyaya giden mutlak yolu elde etmek için yaptıklarını gördüm .

Ancak bunu buluyorum os.path.abspath(__file__)ve os.path.realpath(__file__)aynı sonucu veriyorum . os.path.abspath(os.path.realpath(__file__))biraz gereksiz görünüyor.

İnsanların bunu kullanmasının bir nedeni var mı?

Yanıtlar:


67

os.path.realpath onları destekleyen işletim sistemlerindeki sembolik bağları kaldırır.

os.path.abspathbasitçe gibi şeyler kaldırır .ve ..adlandırılmış dosya (veya sembolik bağı) dizin ağacının kökünden tam yol vererek yoldan

Örneğin, Ubuntu'da

$ 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'

Sembolik bağlantılar göreceli yollar içerebilir, dolayısıyla her ikisinin de kullanılması gerekir. İç çağrı , daha sonra kaldırılan realpathgömülü ..parçalar içeren bir yol döndürebilir abspath.


10
Bu cevap iki işlev arasındaki farkı açıklasa da sonucunun bileşenleri realpath()içerebileceği ..ve neden ikisini birden kullanacağınız sorusuna gerçekten cevap vermediği doğru değildir; jobrad'ın cevabı daha doğru.
Miles

Python 3.7 ve pencereler için, realpath trafolu sürücüleri anlamıyor Bu nedenle, bir alt sürücü için, c: \ MyFolder \ Bla kaynak klasörüne sahip olan P: \ deyin, realpath, P: \ not c: \ MyFolder \ Bla döndürür. "Gerçek" yolu nasıl elde edeceğini bilen var mı?
Totte Karlsson

Benim için, abspathmevcut dizin bir sembolik bağ ise sembolik bağları takip etmeye devam ediyor. Bu yanıtı yalnızca bu davranışı durdurmak için stackoverflow.com/questions/54665065/… buldum .
Victor Sergienko

113

Belirtilen senaryonuz için, realpath ve abspath'i birleştirmek için bir neden yok, çünkü os.path.realpathaslında os.path.abspathbir sonuç döndürmeden önce çağırıyor (Python 2.5'ten Python 3.6'ya baktım).

  • os.path.abspath mutlak yolu döndürür, ancak argümanındaki sembolik bağları ÇÖZMEZ.
  • os.path.realpath önce yoldaki herhangi bir sembolik bağı çözecek ve sonra mutlak yolu döndürecektir.

Ancak, yolunuzun a içermesini bekliyorsanız ~, ne abspath ne de realpath ~kullanıcının ev dizinine çözümlenmeyecek ve sonuçta ortaya çıkan yol geçersiz olacaktır . Bunu os.path.expanduserkullanıcının dizinine çözmek için kullanmanız gerekecek .

Kapsamlı bir açıklama adına, burada Windows ve Linux'ta, Python 3.4 ve Python 2.6'da doğruladığım bazı sonuçlar var. Geçerli dizin ( ./), şuna benzeyen benim ana dizinimdir:

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
Güzel. os.path.realpath(os.path.expanduser('~/subdir/../data'))
Arthur

4
O zaman, değişkenler bir yolda kullanılıyorsa os.path.expandvars'ı da unutmayın
Slavenskij

9

Layman terimleriyle, bir kısayol dosyasının yolunu almaya çalışıyorsanız, mutlak yol, kısayol konumunda bulunan dosyanın tam yolunu verirken, realpath dosyanın orijinal konum yolunu verir .

Mutlak yol, os.path.abspath (), geçerli çalışma dizininde veya bahsettiğiniz dizinde bulunan dosyanın tam yolunu verir.

Gerçek yol, os.path.realpath (), başvurulan dosyanın tam yolunu verir.

Örneğin:

file = "shortcut_folder/filename"
os.path.abspath(file) = "C:/Desktop/shortcut_folder/filename"
os.path.realpath(file) = "D:/PyCharmProjects/Python1stClass/filename"
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.