Tại sao một người sẽ sử dụng cả hai, os.path.abspath và os.path.realpath?


98

Trong nhiều dự án mã nguồn mở, tôi đã thấy mọi người làm os.path.abspath(os.path.realpath(__file__))để có được đường dẫn tuyệt đối đến tệp hiện tại.

Tuy nhiên, tôi tìm thấy điều đó os.path.abspath(__file__)os.path.realpath(__file__)tạo ra kết quả tương tự. os.path.abspath(os.path.realpath(__file__))có vẻ là hơi thừa.

Có lý do gì mà mọi người đang sử dụng nó?

Câu trả lời:


66

os.path.realpath bỏ các liên kết tượng trưng trên những hệ điều hành hỗ trợ chúng.

os.path.abspathchỉ cần loại bỏ những thứ như ...khỏi đường dẫn cung cấp một đường dẫn đầy đủ từ gốc của cây thư mục đến tệp được đặt tên (hoặc liên kết biểu tượng)

Ví dụ: trên 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'

Các liên kết tượng trưng có thể chứa các đường dẫn tương đối, do đó cần phải sử dụng cả hai. Lệnh gọi bên trong realpathcó thể trả về một đường dẫn với các ..phần được nhúng , abspathsau đó sẽ loại bỏ.


10
Mặc dù câu trả lời này mô tả sự khác biệt giữa hai hàm, nhưng không đúng là kết quả của realpath()có thể chứa ..các thành phần và không thực sự trả lời câu hỏi tại sao bạn lại sử dụng cả hai; câu trả lời của jobrad chính xác hơn.
Miles

Đối với Python 3.7 và windows, đường dẫn thực không hiểu các ổ đĩa con Vì vậy, đối với một ổ đĩa con nói P: \, có thư mục nguồn c: \ MyFolder \ Bla, đường dẫn thực trả về P: \ not c: \ MyFolder \ Bla. Bất cứ ai biết làm thế nào để có được con đường "thực sự"?
Totte Karlsson

Đối với tôi, abspathvẫn theo sau các liên kết tượng trưng nếu thư mục hiện tại là một liên kết tượng trưng. Tôi chỉ tìm thấy câu trả lời này stackoverflow.com/questions/54665065/… để dừng hành vi này.
Victor Sergienko

108

Đối với kịch bản đã nêu của bạn, không có lý do gì để kết hợp realpath và abspath, vì os.path.realpaththực sự các lệnh gọi os.path.abspathtrước khi trả về kết quả (tôi đã kiểm tra Python 2.5 đến Python 3.6).

  • os.path.abspath trả về đường dẫn tuyệt đối, nhưng KHÔNG giải quyết các liên kết tượng trưng trong đối số của nó.
  • os.path.realpath trước tiên sẽ giải quyết bất kỳ liên kết tượng trưng nào trong đường dẫn, sau đó trả về đường dẫn tuyệt đối.

Tuy nhiên, nếu bạn mong đợi con đường của bạn để chứa một ~, không phải abspath hoặc realpath sẽ giải quyết ~vào thư mục chính của người dùng, và đường dẫn kết quả sẽ là không hợp lệ . Bạn sẽ cần phải sử dụng os.path.expanduserđể giải quyết điều này vào thư mục của người dùng.

Để giải thích cặn kẽ, đây là một số kết quả mà tôi đã xác minh trong Windows và Linux, bằng Python 3.4 và Python 2.6. Thư mục hiện tại ( ./) là thư mục chính của tôi, trông giống như sau:

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
Đẹp. Để làm rõ quan điểm của bạn, ví dụ cuối cùng của bạn phải làos.path.realpath(os.path.expanduser('~/subdir/../data'))
Arthur

3
Sau đó, cũng đừng quên về os.path.expandvars nếu các biến được sử dụng trong một đường dẫn
Slavenskij

8

Theo thuật ngữ của người quản lý, nếu bạn đang cố gắng lấy đường dẫn của tệp lối tắt, đường dẫn tuyệt đối cung cấp đường dẫn hoàn chỉnh của tệp có trong vị trí lối tắt , trong khi đường dẫn thực cung cấp đường dẫn vị trí ban đầu của tệp.

Đường dẫn tuyệt đối, os.path.abspath (), cung cấp đường dẫn đầy đủ của tệp nằm trong thư mục làm việc hiện tại hoặc thư mục bạn đã đề cập.

Đường dẫn thực, os.path.realpath (), cung cấp đường dẫn đầy đủ của tệp đang được tham chiếu.

Ví dụ:

file = "shortcut_folder/filename"
os.path.abspath(file) = "C:/Desktop/shortcut_folder/filename"
os.path.realpath(file) = "D:/PyCharmProjects/Python1stClass/filename"
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.