Saya memiliki skrip yang memanggil file skrip lain tetapi saya perlu mendapatkan filepath dari file yang sedang berjalan dalam proses.
Sebagai contoh, katakanlah saya punya tiga file. Menggunakan execfile :
script_1.py
panggilanscript_2.py
.- Pada gilirannya,
script_2.py
panggilanscript_3.py
.
Bagaimana saya bisa mendapatkan nama file dan jalur script_3.py
, dari kode di dalamscript_3.py
, tanpa harus meneruskan informasi itu sebagai argumen dari script_2.py
?
(Melaksanakan os.getcwd()
mengembalikan filepath skrip awal asli bukan file saat ini.)
__file__
absolut atau relatif?Jawaban:
p1.py:
p2.py:
sumber
inspect.getabsfile()
dan berhasil untuk semua kasus yang saya coba.os.path.realpath(__file__)
seperti yang orang lain katakan. Anda mungkin juga ingin menggunakan os.path.realpath untuk menghilangkan symlink:
sumber
__file__
mengembalikan 'script_name.py', dan lain kali 'script_name.pyc'. Jadi output tidak stabil."__file__"
dalam tanda kutip (sebagai string) memberikan dir dari mana cmd dijalankan, tetapi__file__
(tanpa tanda kutip memberikan path ke file sumber ... mengapa begituos.path.realpath
fungsi yang mengasumsikandir
bagian dari path menjadi.os.path.dirname(os.path.realpath(__file__))
mengembalikan direktori dengan file.os.path.dirname(os.path.realpath("__file__"))
mengembalikan cwd.os.path.dirname(os.path.realpath("here_be_dragons"))
juga mengembalikan cwd.Pembaruan 2018-11-28:
Berikut ini adalah ringkasan percobaan dengan Python 2 dan 3. With
main.py - menjalankan foo.py
foo.py - menjalankan lib / bar.py
lib / bar.py - mencetak ekspresi filepath
Untuk Python 2, mungkin lebih jelas untuk beralih ke paket sehingga dapat menggunakan
from lib import bar
- cukup tambahkan__init__.py
file kosong ke dua folder.Untuk Python 3,
execfile
tidak ada - alternatif terdekat adalahexec(open(<filename>).read())
, meskipun ini mempengaruhi bingkai tumpukan. Ini paling sederhana untuk hanya menggunakanimport foo
danimport lib.bar
- tidak__init__.py
perlu file.Lihat juga Perbedaan antara impor dan execfile
Jawaban asli:
Berikut adalah eksperimen berdasarkan jawaban di utas ini - dengan Python 2.7.10 di Windows.
Yang berbasis tumpukan adalah satu-satunya yang tampaknya memberikan hasil yang dapat diandalkan. Dua yang terakhir memiliki sintaks terpendek , yaitu -
Ini untuk ini ditambahkan ke sys sebagai fungsi! Kredit ke @Usagi dan @pablog
Berdasarkan tiga file berikut, dan menjalankan main.py dari foldernya dengan
python main.py
(juga mencoba execfile dengan path absolut dan memanggil dari folder terpisah).C: \ filepaths \ main.py:
execfile('foo.py')
C: \ filepaths \ foo.py:
execfile('lib/bar.py')
C: \ filepaths \ lib \ bar.py:
sumber
Saya pikir ini lebih bersih:
dan mendapatkan informasi yang sama dengan:
Di mana [0] adalah bingkai saat ini di tumpukan (atas tumpukan) dan [1] adalah untuk nama file, naikkan untuk mundur dalam tumpukan yaitu
akan menjadi nama file dari skrip yang disebut frame saat ini. Selain itu, menggunakan [-1] akan membawa Anda ke bagian bawah tumpukan, skrip panggilan asli.
sumber
inspect.getfile()
mengembalikan__file__
atribut jika melewati objek modul.inspect.currentframe()
mengembalikan modul. Ergo, ini cara mengatakan yang mahal__file__
.inspect.stack()
adalah fungsi yang cukup mahal, lebih dari sekadarinspect.currentframe()
, dan itu juga memanggilinspect.getfile()
objek modul.sumber
__file__
.os.path.dirname
akan memberi Anda jalur relatif dari tempat Anda menjalankan skrip. misalnya dipython ../../test.py
dalamos.path.dirname
akan../../
dan bukan jalan mutlak untuk script. Saya mencari abspath tetapi menghapus nama skrip. Elemen pertama dari sys.path tampaknya adalah jawabannyasys.path[0]
.Saran yang ditandai sebagai yang terbaik semuanya benar jika skrip Anda hanya terdiri dari satu file.
Jika Anda ingin mengetahui nama yang dapat dieksekusi (yaitu file root yang diteruskan ke interpreter python untuk program saat ini) dari file yang dapat diimpor sebagai modul, Anda perlu melakukan ini (anggap ini ada dalam file bernama foo.py ):
import inspect
print inspect.stack()[-1][1]
Karena hal terakhir (
[-1]
) pada stack adalah hal pertama yang masuk ke dalamnya (tumpukan adalah struktur data LIFO / FILO).Kemudian di file bar.py jika Anda
import foo
akan mencetak bar.py , bukan foo.py , yang akan menjadi nilai dari semua ini:__file__
inspect.getfile(inspect.currentframe())
inspect.stack()[0][1]
sumber
sys.modules['__main__'].__file__
, sungguh.ini akan memberi kita nama file saja. yaitu jika abspath file adalah c: \ abcd \ abc.py maka baris ke-2 akan mencetak abc.py
sumber
Tidak sepenuhnya jelas apa yang Anda maksud dengan "filepath dari file yang sedang berjalan dalam proses".
sys.argv[0]
biasanya berisi lokasi skrip yang dipanggil oleh juru bahasa Python. Periksa dokumentasi sistem untuk lebih jelasnya.Seperti yang ditunjukkan oleh @Tim dan @Pat Notz, atribut __file__ menyediakan akses ke
sumber
Saya memiliki skrip yang harus berfungsi di bawah lingkungan windows. Kode ini terpotong dengan apa yang telah saya selesaikan:
itu keputusan yang cukup gila. Tapi itu tidak memerlukan perpustakaan eksternal dan itu adalah hal yang paling penting dalam kasus saya.
sumber
Coba ini,
sumber
Tidak perlu memeriksa atau perpustakaan lain.
Ini bekerja untuk saya ketika saya harus mengimpor skrip (dari direktori yang berbeda kemudian skrip yang dieksekusi), yang menggunakan file konfigurasi yang berada di folder yang sama dengan skrip yang diimpor.
sumber
The
__file__
atribut bekerja untuk kedua file yang berisi kode eksekusi utama sebagai modul serta impor.Lihat https://web.archive.org/web/20090918095828/http://pyref.infogami.com/__file__
sumber
ini akan mencetak jalur skrip yang saat ini sedang dijalankan
sumber
Saya pikir itu hanya
__file__
Kedengarannya seperti Anda mungkin juga ingin checkout modul inspeksi .sumber
Kamu bisa menggunakan
inspect.stack()
sumber
Karena Python 3 cukup umum, saya ingin memasukkan
pathlib
jawaban, karena saya percaya itu mungkin sekarang menjadi alat yang lebih baik untuk mengakses informasi file dan path.Jika Anda sedang mencari direktori dari file saat ini, itu adalah semudah menambahkan
.parent
kePath()
pernyataan:sumber
sumber
Ini seharusnya bekerja:
sumber
sumber
Untuk mendapatkan direktori skrip pelaksana
sumber
Saya selalu menggunakan fitur os dari Current Working Directory, atau CWD. Ini adalah bagian dari perpustakaan standar, dan sangat mudah diimplementasikan. Berikut ini sebuah contoh:
sumber
python script.py
perintah di folder yang sama dengan Anda, padahal kenyataannya sama dengan berjalanpwd
di linux.Saya menggunakan pendekatan dengan __file__
os.path.abspath(__file__)
tetapi ada sedikit trik, ia mengembalikan file .py ketika kode dijalankan pertama kali, selanjutnya menjalankan memberi nama file * .pyc
jadi saya tetap dengan:
inspect.getfile(inspect.currentframe())
atau
sys._getframe().f_code.co_filename
sumber
Saya menulis sebuah fungsi yang mempertimbangkan debugger eclipse dan unittest . Ini mengembalikan folder skrip pertama yang Anda luncurkan. Secara opsional Anda dapat menentukan __file__ var, tetapi yang utama adalah Anda tidak perlu membagikan variabel ini di semua hierarki panggilan Anda .
Mungkin Anda dapat menangani tumpukan kasus tertentu yang tidak saya lihat, tetapi bagi saya tidak masalah.
sumber
Untuk menjaga konsistensi migrasi lintas platform (macOS / Windows / Linux), coba:
path = r'%s' % os.getcwd().replace('\\','/')
sumber
Cara paling sederhana adalah:
di script_1.py:
di script_2.py:
PS: Saya sudah mencoba
execfile
, tetapi karena membaca script_2.py sebagai string,sys.argv[0]
dikembalikan<string>
.sumber
Inilah yang saya gunakan sehingga saya dapat membuang kode saya di mana saja tanpa masalah.
__name__
selalu didefinisikan, tetapi__file__
hanya ditentukan ketika kode dijalankan sebagai file (misalnya tidak dalam IDLE / iPython).Atau, ini dapat ditulis sebagai:
sumber
Sebagian besar jawaban ini ditulis dalam Python versi 2.x atau sebelumnya. Dalam Python 3.x sintaks untuk fungsi cetak telah berubah untuk membutuhkan tanda kurung, yaitu cetak ().
Jadi, ini skor jawaban tinggi sebelumnya dari user13993 di Python 2.x:
Menjadi dalam Python 3.x:
sumber
jika Anda hanya menginginkan nama file tanpa
./
atau.py
Anda dapat mencoba inifile_name
akan mencetak skrip Anda dapat menghasilkan apa pun yang Anda inginkan dengan mengubah indeks di dalam []sumber
sumber