Jawaban:
Anda dapat menggunakan __file__
untuk mendapatkan nama file saat ini. Ketika digunakan dalam modul utama, ini adalah nama skrip yang awalnya dipanggil.
Jika Anda ingin menghilangkan bagian direktori (yang mungkin ada), Anda dapat menggunakan os.path.basename(__file__)
.
__file__
tidak didefinisikan dalam interpreter interaktif, karena tidak ada artinya di sana. Ini diatur oleh implementasi impor, jadi jika Anda menggunakan mekanisme impor non-standar mungkin juga tidak disetel.
import os
diperlukan untuk ini untuk bekerja. Saya akan menambahkan ini ke dalam jawabannya.
import os
dan import os.path
sepenuhnya setara.
import sys
print sys.argv[0]
Ini akan mencetak foo.py
untuk python foo.py
, dir/foo.py
untuk python dir/foo.py
, dll. Ini adalah argumen pertama python
. (Perhatikan bahwa setelah py2exe, itu akan menjadi foo.exe
.)
python linkfile.py
, di mana linkfile.py
symlink ke realfile.py
, sys.argv[0]
akan 'linkfile.py'
, yang mungkin atau mungkin tidak apa yang Anda inginkan; tentu saja itu yang saya harapkan . __file__
adalah sama: itu akan terjadi linkfile.py
. Jika Anda ingin mencari 'realfile.py'
dari 'linkfile.py'
, coba os.path.realpath('linkfile.py')
.
__file__
saja.
Demi kelengkapan, saya pikir akan bermanfaat untuk merangkum berbagai hasil yang mungkin dan menyediakan referensi untuk perilaku yang tepat dari masing-masing:
__file__
adalah file yang sedang dieksekusi, sebagaimana dirinci dalam dokumentasi resmi :
__file__
adalah pathname dari file dari mana modul dimuat, jika itu diambil dari file. The__file__
atribut mungkin hilang untuk beberapa jenis modul, seperti C modul yang statis terhubung ke penafsir; untuk modul ekstensi yang dimuat secara dinamis dari perpustakaan bersama, itu adalah nama path dari file perpustakaan bersama.
Dari Python3.4 dan seterusnya, per masalah 18416 , __file__
selalu merupakan jalur absolut, kecuali jika file yang sedang dieksekusi adalah skrip yang telah dieksekusi secara langsung (bukan melalui penerjemah dengan -m
opsi baris perintah) menggunakan jalur relatif.
__main__.__file__
(memerlukan pengimporan __main__
) dengan mudah mengakses __file__
atribut modul utama yang disebutkan di atas , misalnya skrip yang dipanggil dari baris perintah.
sys.argv[0]
(wajib mengimpor sys
) adalah nama skrip yang dipanggil dari baris perintah, dan mungkin merupakan jalur absolut, sebagaimana dirinci dalam dokumentasi resmi :
argv[0]
adalah nama skrip (tergantung pada sistem operasi apakah ini nama path lengkap atau tidak). Jika perintah dieksekusi menggunakan-c
opsi baris perintah ke interpreter,argv[0]
diatur ke string'-c'
. Jika tidak ada nama skrip yang diteruskan ke interpreter Python,argv[0]
adalah string kosong.
Seperti disebutkan dalam jawaban lain untuk pertanyaan ini , skrip Python yang dikonversi menjadi program yang dapat dieksekusi yang berdiri sendiri melalui alat-alat seperti py2exe atau PyInstaller mungkin tidak menampilkan hasil yang diinginkan ketika menggunakan pendekatan ini (yaitu sys.argv[0]
akan menyimpan nama yang dapat dieksekusi daripada nama dari file Python utama dalam executable itu).
Jika tidak ada opsi yang disebutkan di atas yang berfungsi, mungkin karena operasi impor yang tidak teratur, modul inspeksi mungkin terbukti bermanfaat. Secara khusus, memohon inspect.getfile(...)
pada inspect.currentframe()
bisa bekerja, meskipun yang terakhir akan kembaliNone
ketika berjalan di sebuah implementasi tanpa Python stack frame.
Jika skrip saat ini adalah tautan simbolik, maka semua yang di atas akan mengembalikan jalur tautan simbolik daripada path file asli dan os.path.realpath(...)
harus dipanggil untuk mengekstrak yang terakhir.
os.path.basename(...)
dapat dipanggil pada salah satu di atas untuk mengekstrak nama file yang sebenarnya dan os.path.splitext(...)
dapat dipanggil pada nama file yang sebenarnya untuk memotong sufiksnya, seperti padaos.path.splitext(os.path.basename(...))
.
Dari Python 3,4 dan seterusnya, per PEP 428 , yang PurePath
kelas dari pathlib
modul dapat digunakan juga pada apapun di atas. Secara khusus, pathlib.PurePath(...).name
mengekstrak nama file aktual dan pathlib.PurePath(...).stem
mengekstraksi nama file aktual tanpa akhiran.
Catatan yang __file__
akan memberikan file tempat kode ini berada, yang dapat diimpor dan berbeda dari file utama yang ditafsirkan. Untuk mendapatkan file utama, modul __main__ khusus dapat digunakan:
import __main__ as main
print(main.__file__)
Catatan yang __main__.__file__
berfungsi di Python 2.7 tetapi tidak di 3.2, jadi gunakan sintaks import-as seperti di atas untuk membuatnya portabel.
rPython
paket dari R
bahasa. Itu pasti kasus luar biasa yang terlalu sulit untuk ditangani.
__main__
internal, untuk digunakan dalam melewati variabel antara R
dan python
, jadi itu akan relatif mudah untuk membuatnya ditetapkan __main__.__file__
sebelum memanggil yang lain, tapi saya bahkan tidak yakin apa yang akan menjadi nilai yang sesuai dalam kasus ini.
Jawaban di atas baik. Tetapi saya menemukan metode ini lebih efisien menggunakan hasil di atas.
Ini menghasilkan nama file skrip aktual bukan jalur.
import sys
import os
file_name = os.path.basename(sys.argv[0])
Untuk versi Python modern (3.4+), Path(__file__).name
harus lebih idiomatis. Juga, Path(__file__).stem
memberi Anda nama skrip tanpa .py
ekstensi.
from pathlib import Path
terlebih dahulu.
pathlib
diperkenalkan dengan Python 3.4, jadi harusnya mulai dari Python 3.4.
Dengan asumsi bahwa nama file adalah foo.py
, potongan di bawah ini
import sys
print sys.argv[0][:-3]
atau
import sys
print sys.argv[0][::-1][3:][::-1]
Adapun perluasan lain dengan lebih banyak karakter, misalnya nama file foo.pypy
import sys
print sys.argv[0].split('.')[0]
Jika Anda ingin mengekstrak dari jalur absolut
import sys
print sys.argv[0].split('/')[-1].split('.')[0]
akan menampilkan foo
Argumen pertama dalam sys akan menjadi nama file saat ini sehingga ini akan berfungsi
import sys
print sys.argv[0] # will print the file name
Jika Anda melakukan impor yang tidak biasa (mis., Ini adalah file opsi), cobalah:
import inspect
print (inspect.getfile(inspect.currentframe()))
Perhatikan bahwa ini akan mengembalikan path absolut ke file.
kita dapat mencoba ini untuk mendapatkan nama skrip saat ini tanpa ekstensi.
import os
script_name = os.path.splitext(os.path.basename(__file__))[0]
semua jawaban itu bagus, tetapi memiliki beberapa masalah Anda mungkin tidak melihat pada pandangan pertama.
mari tentukan apa yang kita inginkan - kita ingin nama skrip yang dieksekusi, bukan nama modul saat ini - jadi __file__
hanya akan berfungsi jika digunakan pada skrip yang dieksekusi, bukan dalam modul yang diimpor.
sys.argv
juga dipertanyakan - bagaimana jika program Anda dipanggil oleh pytest? atau pydoc runner? atau apakah itu disebut oleh uwsgi?
dan - ada metode ketiga untuk mendapatkan nama skrip, saya belum melihat dalam jawaban - Anda dapat memeriksa tumpukan.
Masalah lain adalah, bahwa Anda (atau program lain) dapat mengutak-atik sys.argv
dan__main__.__file__
- mungkin ada, mungkin tidak. Mungkin valid, atau tidak. Setidaknya Anda dapat memeriksa apakah skrip (hasil yang diinginkan) ada!
bitranox perpustakaan saya / lib_programname di github melakukan hal itu:
__main__
ada__main__.__file__
ada__main__.__file__
hasil yang valid (apakah skrip itu ada?)dengan cara itu, solusi saya bekerja sejauh ini dengan setup.py test
, uwsgi
, pytest
, pycharm pytest
, pycharm docrunner (doctest)
, dreampie
,eclipse
ada juga artikel blog yang bagus tentang masalah itu dari Dough Hellman, "Menentukan Nama Proses dari Python"
Solusi cepat kotor saya:
__file__.split('/')[-1:][0]
os.path
untuk membagi nama file
os.path.abspath(__file__)
akan memberi Anda jalur absolut ( relpath()
tersedia juga).
sys.argv[-1]
akan memberi Anda jalan relatif.
Pada Python 3.5, Anda cukup melakukan:
from pathlib import Path
Path(__file__).stem
Lihat lebih lanjut di sini: https://docs.python.org/3.5/library/pathlib.html#pathlib.PurePath.stem
Sebagai contoh, saya memiliki file di bawah direktori pengguna saya bernama test.py
dengan ini di dalam:
from pathlib import Path
print(Path(__file__).stem)
print(__file__)
menjalankan output ini:
>>> python3.6 test.py
test
test.py
Exception NameError: NameError("global name '__file__' is not defined",)
"