Lấy vị trí (đường dẫn) của một tệp đang chạy bằng Python: __file__.

Kinh doanh

Để lấy vị trí (đường dẫn) của tệp script đang chạy bằng Python, hãy sử dụng __file__. Điều này rất hữu ích để tải các tệp khác dựa trên vị trí của tệp đang chạy.

Lên đến Python 3.8, __file__ trả về đường dẫn được chỉ định khi thực thi lệnh python (hoặc lệnh python3 trong một số môi trường). Nếu một đường dẫn tương đối được chỉ định, đường dẫn tương đối được trả về; nếu một đường dẫn tuyệt đối được chỉ định, đường dẫn tuyệt đối được trả về.

Trong Python 3.9 trở lên, đường dẫn tuyệt đối được trả về bất kể đường dẫn được chỉ định trong thời gian chạy.

Nội dung sau đây được giải thích.

  • os.getcwd(),__file__
  • Lấy tên tệp và tên thư mục của tệp đang thực thi.
  • Lấy đường dẫn tuyệt đối của tệp đang được thực thi.
  • Đọc các tệp khác dựa trên vị trí của tệp hiện đang thực thi.
  • Di chuyển thư mục hiện tại đến thư mục của tệp đang được thực thi.
  • Quá trình xử lý tương tự có thể được thực hiện bất kể thư mục hiện tại trong thời gian chạy.

Xem bài viết sau để biết thông tin về cách lấy và thay đổi thư mục hiện tại (thư mục làm việc).

Lưu ý rằng __file__ không thể được sử dụng trong Máy tính xách tay Jupyter (.ipynb).
Thư mục chứa .ipynb sẽ được thực thi dưới dạng thư mục hiện tại, bất kể thư mục mà Jupyter Notebook được khởi động.
Có thể sử dụng os.chdir () trong mã để thay đổi thư mục hiện tại.

os.getcwd () và __file__.

Trong Windows, bạn có thể sử dụng lệnh dir thay vì pwd để kiểm tra thư mục hiện tại.

pwd
# /Users/mbp/Documents/my-project/python-snippets/notebook

Tạo tệp tập lệnh Python (file_path.py) với nội dung sau ở cấp thấp hơn (data \ src).

import os

print('getcwd:      ', os.getcwd())
print('__file__:    ', __file__)

Chạy lệnh python (hoặc lệnh python3 trong một số môi trường) chỉ định đường dẫn đến tệp kịch bản.

python3 data/src/file_path.py
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook
# __file__:     data/src/file_path.py

Đường dẫn tuyệt đối đến thư mục hiện tại có thể được lấy bằng os.getcwd (). Bạn cũng có thể sử dụng __file__ để lấy đường dẫn được chỉ định bởi lệnh python3.

Lên đến Python 3.8, __file__ sẽ chứa đường dẫn được chỉ định trong lệnh python (hoặc python3). Trong ví dụ trên, đường dẫn tương đối được trả về vì nó là tương đối, nhưng đường dẫn tuyệt đối được trả về nếu nó là tuyệt đối.

pwd
# /Users/mbp/Documents/my-project/python-snippets/notebook

python3 /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook
# __file__:     /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py

Python 3.9 trở lên trả về đường dẫn tuyệt đối đến __file__, bất kể đường dẫn được chỉ định trong lệnh python (hoặc python3).

Trong ví dụ sau, chúng tôi sẽ thêm mã vào cùng một tệp script (file_path.py) trong Python 3.7 và chạy nó liên quan đến thư mục trên.

Trong Python 3.7, đường dẫn tuyệt đối được sử dụng. Kết quả được hiển thị ở cuối phần này.

Lấy tên tệp và tên thư mục của tệp đang thực thi.

Để lấy tên tệp và tên thư mục của tệp đang chạy, hãy sử dụng hàm sau trong mô-đun os.path của thư viện chuẩn.

  • os.path.basename()
  • os.path.dirname()
print('basename:    ', os.path.basename(__file__))
print('dirname:     ', os.path.dirname(__file__))

Kết quả thực thi.

# basename:     file_path.py
# dirname:      data/src

Lấy đường dẫn tuyệt đối của tệp đang được thực thi.

Nếu một đường dẫn tương đối được lấy bằng __file__, nó có thể được chuyển đổi thành một đường dẫn tuyệt đối với os.path.abspath (). Thư mục cũng có thể được lấy dưới dạng đường dẫn tuyệt đối.

print('abspath:     ', os.path.abspath(__file__))
print('abs dirname: ', os.path.dirname(os.path.abspath(__file__)))

Kết quả thực thi.

# abspath:      /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# abs dirname:  /Users/mbp/Documents/my-project/python-snippets/notebook/data/src

Nếu một đường dẫn tuyệt đối được chỉ định trong os.path.abspath (), nó sẽ được trả về nguyên trạng. Do đó, nếu __file__ là một đường dẫn tuyệt đối, thì phần sau sẽ không gây ra lỗi.

  • os.path.abspath(__file__)

Đọc các tệp khác dựa trên vị trí của tệp hiện đang thực thi.

Nếu bạn muốn đọc các tệp khác dựa trên vị trí (đường dẫn) của tệp đang được thực thi, hãy nối hai tệp sau bằng cách sử dụng os.path.join ().

  • Thư mục của tệp đang được thực thi
  • Đường dẫn tương đối đến tệp được đọc từ tệp đang chạy.

Nếu bạn muốn đọc một tệp trong cùng thư mục với tệp bạn đang chạy, chỉ cần nối tên tệp.

print('[set target path 1]')
target_path_1 = os.path.join(os.path.dirname(__file__), 'target_1.txt')

print('target_path_1: ', target_path_1)

print('read target file:')
with open(target_path_1) as f:
    print(f.read())

Kết quả thực thi.

# [set target path 1]
# target_path_1:  data/src/target_1.txt
# read target file:
# !! This is "target_1.txt" !!

Cấp trên được biểu thị bằng “. \”. Bạn có thể để nguyên như vậy, nhưng bạn có thể sử dụng os.path.normpath () để bình thường hóa đường dẫn và xóa thêm “. \” Và các ký tự khác.

print('[set target path 2]')
target_path_2 = os.path.join(os.path.dirname(__file__), '../dst/target_2.txt')

print('target_path_2: ', target_path_2)
print('normalize    : ', os.path.normpath(target_path_2))

print('read target file:')
with open(target_path_2) as f:
    print(f.read())

Kết quả thực thi.

# [set target path 2]
# target_path_2:  data/src/../dst/target_2.txt
# normalize    :  data/dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!

Di chuyển thư mục hiện tại đến thư mục của tệp đang được thực thi.

Sử dụng os.chdir () để di chuyển thư mục hiện tại đến thư mục của tệp đang được thực thi trong tập lệnh.

Bạn có thể thấy rằng nó được di chuyển bởi os.getcwd ().

print('[change directory]')
os.chdir(os.path.dirname(os.path.abspath(__file__)))
print('getcwd:      ', os.getcwd())

Kết quả thực thi.

# [change directory]
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook/data/src

Khi thư mục hiện tại đã được di chuyển, không cần phải nối nó với thư mục của tệp đang chạy khi đọc tệp. Bạn chỉ có thể chỉ định đường dẫn liên quan đến thư mục của tệp đang chạy.

print('[set target path 1 (after chdir)]')
target_path_1 = 'target_1.txt'

print('target_path_1: ', target_path_1)

print('read target file:')
with open(target_path_1) as f:
    print(f.read())

print()
print('[set target path 2 (after chdir)]')
target_path_2 = '../dst/target_2.txt'

print('target_path_2: ', target_path_2)

print('read target file:')
with open(target_path_2) as f:
    print(f.read())

Kết quả thực thi.

# [set target path 1 (after chdir)]
# target_path_1:  target_1.txt
# read target file:
# !! This is "target_1.txt" !!
# 
# [set target path 2 (after chdir)]
# target_path_2:  ../dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!

Quá trình xử lý tương tự có thể được thực hiện bất kể thư mục hiện tại trong thời gian chạy.

Như chúng tôi đã trình bày, có thể tải các tệp dựa trên vị trí của tệp script, độc lập với thư mục hiện tại trong thời gian chạy, bằng cách sử dụng một trong các phương pháp sau.

  • Nối thư mục của tệp đang chạy và đường dẫn tương đối đến tệp sẽ được đọc từ tệp đang chạy bằng cách sử dụng os.path.join ().
  • Di chuyển thư mục hiện tại đến thư mục của tệp đang được thực thi.

Việc di chuyển thư mục hiện tại sẽ dễ dàng hơn, nhưng tất nhiên, nếu bạn muốn đọc hoặc ghi nhiều tệp hơn sau đó, bạn cần tính đến việc thư mục hiện tại đã được di chuyển.

Kết quả của các ví dụ trước được tóm tắt dưới đây.

pwd
# /Users/mbp/Documents/my-project/python-snippets/notebook

python3 data/src/file_path.py
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook
# __file__:     data/src/file_path.py
# basename:     file_path.py
# dirname:      data/src
# abspath:      /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# abs dirname:  /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
# 
# [set target path 1]
# target_path_1:  data/src/target_1.txt
# read target file:
# !! This is "target_1.txt" !!
# 
# [set target path 2]
# target_path_2:  data/src/../dst/target_2.txt
# normalize    :  data/dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!
# 
# [change directory]
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
# 
# [set target path 1 (after chdir)]
# target_path_1:  target_1.txt
# read target file:
# !! This is "target_1.txt" !!
# 
# [set target path 2 (after chdir)]
# target_path_2:  ../dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!

Kết quả của việc xác định đường dẫn tuyệt đối như sau.

pwd
# /Users/mbp/Documents/my-project/python-snippets/notebook

python3 /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook
# __file__:     /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# basename:     file_path.py
# dirname:      /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
# abspath:      /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# abs dirname:  /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
# 
# [set target path 1]
# target_path_1:  /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/target_1.txt
# read target file:
# !! This is "target_1.txt" !!
# 
# [set target path 2]
# target_path_2:  /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/../dst/target_2.txt
# normalize    :  /Users/mbp/Documents/my-project/python-snippets/notebook/data/dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!
# 
# [change directory]
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
# 
# [set target path 1 (after chdir)]
# target_path_1:  target_1.txt
# read target file:
# !! This is "target_1.txt" !!
# 
# [set target path 2 (after chdir)]
# target_path_2:  ../dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!

Kết quả của việc di chuyển thư mục hiện tại trong terminal và thực thi cùng một tệp script được hiển thị bên dưới. Bạn có thể thấy rằng cùng một tệp có thể được đọc ngay cả khi nó được thực thi từ một vị trí khác.

cd data/src

pwd
# /Users/mbp/Documents/my-project/python-snippets/notebook/data/src

python3 file_path.py
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
# __file__:     file_path.py
# basename:     file_path.py
# dirname:      
# abspath:      /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# abs dirname:  /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
# 
# [set target path 1]
# target_path_1:  target_1.txt
# read target file:
# !! This is "target_1.txt" !!
# 
# [set target path 2]
# target_path_2:  ../dst/target_2.txt
# normalize    :  ../dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!
# 
# [change directory]
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
# 
# [set target path 1 (after chdir)]
# target_path_1:  target_1.txt
# read target file:
# !! This is "target_1.txt" !!
# 
# [set target path 2 (after chdir)]
# target_path_2:  ../dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!

Copied title and URL