Biến __file__ có nghĩa là gì / làm gì?


177
A = os.path.join(os.path.dirname(__file__), '..')

B = os.path.dirname(os.path.realpath(__file__))

C = os.path.abspath(os.path.dirname(__file__))

Tôi thường chỉ hardwire những điều này với đường dẫn thực tế. Nhưng có một lý do cho những câu lệnh này xác định đường dẫn trong thời gian chạy và tôi thực sự muốn sử dụng mô đun os.path để tôi có thể bắt đầu sử dụng nó.

Câu trả lời:


162

Khi một mô-đun được tải từ một tệp trong Python, __file__được đặt thành đường dẫn của nó. Sau đó, bạn có thể sử dụng chức năng đó với các chức năng khác để tìm thư mục chứa tệp.

Lấy ví dụ của bạn một lần:

A = os.path.join(os.path.dirname(__file__), '..')
# A is the parent directory of the directory where program resides.

B = os.path.dirname(os.path.realpath(__file__))
# B is the canonicalised (?) directory where the program resides.

C = os.path.abspath(os.path.dirname(__file__))
# C is the absolute path of the directory where the program resides.

Bạn có thể thấy các giá trị khác nhau được trả về từ đây:

import os
print(__file__)
print(os.path.join(os.path.dirname(__file__), '..'))
print(os.path.dirname(os.path.realpath(__file__)))
print(os.path.abspath(os.path.dirname(__file__)))

và đảm bảo bạn chạy nó từ các vị trí khác nhau (chẳng hạn như ./text.py, ~/python/text.pyv.v.) để xem điều gì làm nên sự khác biệt.


7
Câu trả lời tốt, nhưng xem chi tiết quan trọng khác từ các câu trả lời khác: __file__KHÔNG được xác định trong mọi trường hợp, ví dụ: các mô-đun C được liên kết tĩnh. Chúng tôi không thể tin vào việc __file__luôn luôn có sẵn.
Chris Johnson

5
Trong phiên dịch, tất cả các ví dụ trở lại name '__file__' is not defined.
dùng1063287

10
@ user1063287 Hãy xem câu trả lời của DemoUser; __file__là tên đường dẫn của tệp mà mô-đun được tải, nếu nó được tải từ một tệp. Điều này có nghĩa là __file__sẽ chỉ hoạt động khi bạn chạy nó dưới dạng một tập lệnh không có trong trình thông dịch. (Trừ khi bạn nhập nó trong trình thông dịch ...)
YOUNG

59

Tôi chỉ muốn giải quyết một số nhầm lẫn đầu tiên. __file__không phải là ký tự đại diện, nó là một thuộc tính. Các thuộc tính và phương thức gạch dưới đôi được coi là "đặc biệt" theo quy ước và phục vụ một mục đích đặc biệt.

http://docs.python.org/reference/datamodel.html hiển thị nhiều phương thức và thuộc tính đặc biệt, nếu không phải tất cả chúng.

Trong trường hợp __file__này là một thuộc tính của một mô-đun (một đối tượng mô-đun). Trong Python một .pytệp là một mô-đun. Vì vậy, import amodulesẽ có một thuộc tính __file__có nghĩa là những thứ khác nhau trong các trường hợp khác nhau.

Lấy từ các tài liệu:

__file__là tên đường dẫn của tệp mà mô-đun được tải, nếu nó được tải từ một tệp. Các __file__thuộc tính là không có mặt cho module C được liên kết tĩnh thành người phiên dịch; đối với các mô-đun mở rộng được tải động từ thư viện dùng chung, đó là tên đường dẫn của tệp thư viện dùng chung.

Trong trường hợp của bạn, mô-đun đang truy cập __file__thuộc tính của chính nó trong không gian tên toàn cục.

Để thấy điều này trong hành động hãy thử:

# file: test.py

print globals()
print __file__

Và chạy:

python test.py

{'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', '__file__':
 'test_print__file__.py', '__doc__': None, '__package__': None}
test_print__file__.py

23

Theo tài liệu :

__file__là tên đường dẫn của tệp mà mô-đun được tải, nếu nó được tải từ một tệp. Các __file__thuộc tính là không có mặt cho module C được liên kết tĩnh thành người phiên dịch; đối với các mô-đun mở rộng được tải động từ thư viện dùng chung, đó là tên đường dẫn của tệp thư viện dùng chung.

cũng :

__file__sẽ là đường dẫn trên đường hướng tới tập tin, trừ khi mô-đun được tích hợp sẵn (và do đó được liệt kê trong sys.builtin_module_names) trong trường hợp đó thuộc tính không được đặt.


13

Việc sử dụng __file__kết hợp với các os.pathmô-đun khác nhau cho phép tất cả các đường dẫn có liên quan đến vị trí thư mục của mô-đun hiện tại. Điều này cho phép các mô-đun / dự án của bạn có thể được chuyển sang các máy khác.

Trong dự án của bạn, bạn làm:

A = '/Users/myname/Projects/mydevproject/somefile.txt'

và sau đó thử triển khai nó đến máy chủ của bạn bằng một thư mục triển khai như /home/web/mydevproject/sau đó mã của bạn sẽ không thể tìm thấy các đường dẫn một cách chính xác.

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.