apa arti / lakukan variabel __file__?

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__))

Saya biasanya hanya hardwire ini dengan jalan yang sebenarnya. Tapi ada alasan untuk pernyataan ini yang menentukan path saat runtime, dan saya benar-benar ingin memahami modul os.path sehingga saya bisa mulai menggunakannya.

depling
sumber

Jawaban:

162

Ketika modul dimuat dari file dengan Python, __file__diatur ke jalurnya. Anda kemudian dapat menggunakannya dengan fungsi lain untuk menemukan direktori tempat file itu berada.

Mengambil contoh Anda satu per satu:

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.

Anda dapat melihat berbagai nilai yang dikembalikan dari sini:

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__)))

dan pastikan Anda menjalankannya dari lokasi yang berbeda (seperti ./text.py, ~/python/text.pydan sebagainya) untuk melihat perbedaan apa yang terjadi.

paxdiablo
sumber
7
Jawaban yang bagus, tetapi lihat detail penting lainnya dari jawaban lain: __file__TIDAK didefinisikan dalam semua kasus, misalnya modul C yang terhubung secara statis. Kami tidak dapat mengandalkan __file__selalu tersedia.
Chris Johnson
5
Dalam juru bahasa, semua contoh kembali name '__file__' is not defined.
user1063287
10
@ user1063287 Lihatlah jawaban DemoUser; __file__adalah pathname dari file dari mana modul dimuat, jika itu diambil dari file. Ini berarti __file__hanya akan berfungsi bila Anda menjalankannya sebagai skrip yang bukan dalam bahasa juru bahasa. (Kecuali jika Anda mengimpornya dalam bahasa juru bahasa ...)
YOUNG
59

Saya hanya ingin mengatasi beberapa kebingungan terlebih dahulu. __file__bukan wildcard itu adalah atribut. Atribut garis bawah ganda dan metode dianggap "istimewa" oleh konvensi dan melayani tujuan khusus.

http://docs.python.org/reference/datamodel.html menunjukkan banyak metode dan atribut khusus, jika tidak semuanya.

Dalam hal ini __file__adalah atribut modul (objek modul). Dalam Python .pyfile adalah modul. Jadi import amoduleakan memiliki atribut __file__yang artinya berbeda dalam keadaan yang berbeda.

Diambil dari dokumen:

__file__adalah pathname dari file dari mana modul dimuat, jika itu diambil dari file. The __file__atribut tidak hadir untuk modul C yang statis terhubung ke penafsir; untuk modul ekstensi yang dimuat secara dinamis dari pustaka bersama, itu adalah nama path dari file pustaka bersama.

Dalam kasus Anda, modul mengaksesnya sendiri __file__ atributnya di namespace global.

Untuk melihat ini dalam aksi coba:

# file: test.py

print globals()
print __file__

Dan lari:

python test.py

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

Per dokumentasi :

__file__adalah pathname dari file dari mana modul dimuat, jika itu diambil dari file. The __file__atribut tidak hadir untuk modul C yang statis terhubung ke penafsir; untuk modul ekstensi yang dimuat secara dinamis dari pustaka bersama, itu adalah nama path dari file pustaka bersama.

dan juga :

__file__adalah untuk menjadi "jalur" ke file kecuali modul built-in (dan dengan demikian terdaftar dalam sys.builtin_module_names) dalam hal ini atribut tidak disetel.

Sudhir Bastakoti
sumber
13

Menggunakan __file__dikombinasikan dengan berbagai os.pathmodul memungkinkan semua jalur relatif lokasi direktori modul saat ini. Ini memungkinkan modul / proyek Anda menjadi portabel untuk mesin lain.

Dalam proyek Anda, Anda melakukannya:

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

dan kemudian mencoba untuk menyebarkannya ke server Anda dengan direktori penyebaran seperti /home/web/mydevproject/maka kode Anda tidak akan dapat menemukan jalur dengan benar.

Sam Dolan
sumber