Ini mungkin tampak seperti pertanyaan pemula, tetapi tidak. Beberapa pendekatan umum tidak berfungsi dalam semua kasus:
sys.argv [0]
Ini berarti menggunakan path = os.path.abspath(os.path.dirname(sys.argv[0]))
, tetapi ini tidak berfungsi jika Anda menjalankan dari skrip Python lain di direktori lain, dan ini bisa terjadi dalam kehidupan nyata.
__mengajukan__
Ini berarti menggunakan path = os.path.abspath(os.path.dirname(__file__))
, tetapi saya menemukan bahwa ini tidak berhasil:
py2exe
tidak memiliki__file__
atribut, tetapi ada solusinya- Ketika Anda menjalankan dari IDLE dengan
execute()
tidak ada__file__
atribut - OS X 10.6 di mana saya dapatkan
NameError: global name '__file__' is not defined
Pertanyaan terkait dengan jawaban yang tidak lengkap:
- Python - Temukan Path ke File Sedang Dijalankan
- Path ke file saat ini tergantung pada bagaimana saya menjalankan program
- Bagaimana cara mengetahui lintasan skrip yang berjalan dengan Python?
- Ubah direktori ke direktori skrip Python
Saya mencari solusi generik , yang akan bekerja di semua kasus penggunaan di atas.
Memperbarui
Ini adalah hasil dari testcase:
Output dari python a.py (di Windows)
a.py: __file__= a.py
a.py: os.getcwd()= C:\zzz
b.py: sys.argv[0]= a.py
b.py: __file__= a.py
b.py: os.getcwd()= C:\zzz
a.py
#! /usr/bin/env python
import os, sys
print "a.py: sys.argv[0]=", sys.argv[0]
print "a.py: __file__=", __file__
print "a.py: os.getcwd()=", os.getcwd()
print
execfile("subdir/b.py")
subdir / b.py
#! /usr/bin/env python
import os, sys
print "b.py: sys.argv[0]=", sys.argv[0]
print "b.py: __file__=", __file__
print "b.py: os.getcwd()=", os.getcwd()
print
pohon
C:.
| a.py
\---subdir
b.py
NameError: global name '__file__' is not defined
menggunakan file dan ini bukan di dalam IDLE. Pikirkan yang__file__
didefinisikan hanya di dalam modul.__file__
tidak ada hubungannya dengan Unicode. Saya tidak tahu mengapa__file__
tidak didefinisikan tetapi saya mencari solusi generik ini akan bekerja pada semua kasus.some_path/module_locator.py
bukan?Pertama, Anda perlu mengimpor dari
inspect
danos
Selanjutnya, di mana pun Anda ingin mencari file sumber dari yang baru saja Anda gunakan
sumber
NameError: global name '__file__' is not defined
(solusi lain yang menyebabkan ini).lambda:_
. Itu bekerja untuk saya - tidak yakin itu akan selalu berhasil.lambda:0
mungkin berjalan lebih cepat dengan jumlah yang sangat kecil (atau mungkin tidak terlalu kecil ... mungkin menjadi beban langsung atau sesuatu yang bahkan lebih cepat untuk0
vs beban global untuk_
?) Debat apakah itu lebih bersih atau lebih mudah dibaca atau bahkan lebih pintar / tidak jelas.getsourcefile(lambda:0)
akan menjadi tidak berarti dan hanya kembaliNone
jika Anda mencoba menjalankannya pada prompt interaktif (karenalambda
tidak akan ada dalam file sumber apa pun.) Jika Anda ingin tahu dari mana fungsi atau objek lain berasal dari lingkungan yang interaktif, mungkinabspath(getsourcefile(thatFunctionOrObject))
akan lebih membantu bagi Anda?solusi ini sangat kuat bahkan di executables
sumber
entry_point: console_script
, tetapi tidak ada jawaban lain.Saya mengalami masalah yang sama, dan saya pikir ini mungkin menyelesaikan masalah:
Ini berfungsi untuk skrip biasa dan dalam keadaan diam. Yang bisa saya katakan adalah mencobanya untuk orang lain!
Penggunaan khas saya:
Sekarang saya menggunakan __modpath__ bukan __file__.
sumber
__modpath__
harus diganti namanya. Anda juga mungkin tidak perluglobal
pernyataan itu. Kalau tidak +1!module_path()
. yaitumodule_path(lambda _: None)
yang tidak tergantung pada isi naskah yang lain.lambda _: None
dan telah menggunakannya selama hampir dua tahun terakhir, tetapi baru saja saya tahu saya bisa memadatkannya menjadi adillambda:0
. Apakah ada alasan khusus Anda menyarankan formulir yang Anda lakukan, dengan argumen diabaikan_
, alih-alih tanpa argumen sama sekali? Apakah ada sesuatu yang superior tentangNone
awalan dengan spasi bukan hanya0
? Keduanya sama-sama samar, saya pikir, hanya satu yang panjangnya 8 karakter sementara yang lain panjangnya 14 karakter.lambda _:
adalah fungsi yang mengambil satu argumen danlambda:
yang tidak mengambil. Tidak masalah karena fungsinya tidak pernah dipanggil. Demikian juga tidak masalah apa nilai pengembalian yang digunakan. Saya kira saya memilihNone
karena pada saat itu sepertinya menunjukkan itu adalah fungsi yang tidak melakukan apa-apa, tidak pernah disebut lebih baik. Ruang di depannya adalah opsional dan sekali lagi hanya ada untuk meningkatkan keterbacaan (selalu berusaha untuk mengikuti PEP8 adalah membentuk kebiasaan).lambda
, menggunakannya untuk sesuatu yang tidak pernah dimaksudkan untuk dilakukan. Jika Anda mengikuti PEP8, saya pikir konten yang tepat untuk itu adalahpass
, tidakNone
, tapi itu tidak valid untuk memasukkan pernyataan dilambda
, jadi Anda harus memasukkan sesuatu dengan nilai. Ada beberapa hal 2 karakter yang valid yang dapat Anda masukkan, tetapi saya pikir satu-satunya karakter karakter yang valid yang dapat Anda masukkan adalah 0-9 (atau nama variabel karakter tunggal yang ditetapkan di luarlambda
.) Saya pikir yang0
terbaik menunjukkan ketiadaan 0- 9.Jawaban singkatnya adalah tidak ada cara yang dijamin untuk mendapatkan informasi yang Anda inginkan , namun ada heuristik yang bekerja hampir selalu dalam praktik. Anda mungkin melihat Bagaimana cara menemukan lokasi executable di C? . Ini membahas masalah dari sudut pandang C, tetapi solusi yang diusulkan mudah ditranskripsi menjadi Python.
sumber
Lihat jawaban saya untuk pertanyaan Mengimpor modul dari folder induk untuk informasi terkait, termasuk mengapa jawaban saya tidak menggunakan
__file__
variabel tidak dapat diandalkan . Solusi sederhana ini harus kompatibel dengan berbagai sistem operasi seperti modulos
daninspect
datang sebagai bagian dari Python.Pertama, Anda perlu untuk bagian impor memeriksa dan os modul.
Selanjutnya, gunakan baris berikut di tempat lain yang diperlukan dalam kode Python Anda:
Bagaimana itu bekerja:
Dari modul bawaan
os
(uraian di bawah),abspath
alat diimpor.Kemudian
getsourcefile
(uraian di bawah) diimpor dari modul bawaaninspect
.abspath(path)
mengembalikan versi absolut / lengkap dari path filegetsourcefile(lambda:0)
entah bagaimana mendapatkan file sumber internal objek fungsi lambda, jadi kembali'<pyshell#nn>'
ke shell Python atau mengembalikan path file dari kode Python yang saat ini sedang dieksekusi.Menggunakan
abspath
pada hasilgetsourcefile(lambda:0)
harus memastikan bahwa path file yang dihasilkan adalah path file lengkap dari file Python.Solusi yang dijelaskan ini pada awalnya didasarkan pada kode dari jawaban di Bagaimana saya mendapatkan jalur file yang sedang dieksekusi di Python? .
sumber
Anda hanya menelepon:
dari pada:
abspath()
memberi Anda path absolut darisys.argv[0]
(nama file kode Anda) dandirname()
mengembalikan path direktori tanpa nama file.sumber
Ini harus melakukan trik dengan cara lintas platform (selama Anda tidak menggunakan penerjemah atau semacamnya):
sys.path[0]
adalah direktori tempat skrip panggilan Anda berada (tempat pertama ia mencari modul untuk digunakan oleh skrip itu). Kita dapat mengambil nama file itu sendiri dari ujungsys.argv[0]
(yang saya lakukan denganos.path.basename
).os.path.join
hanya menyatukan mereka dengan cara lintas platform.os.path.realpath
pastikan saja jika kita mendapatkan tautan simbolis dengan nama yang berbeda dari skrip itu sendiri kita masih mendapatkan nama skrip yang sebenarnya.Saya tidak punya Mac; jadi, saya belum menguji ini pada satu. Tolong beri tahu saya jika itu berfungsi, seperti yang seharusnya. Saya menguji ini di Linux (Xubuntu) dengan Python 3.4. Perhatikan bahwa banyak solusi untuk masalah ini tidak berfungsi pada Mac (karena saya pernah mendengarnya
__file__
tidak ada pada Mac).Perhatikan bahwa jika skrip Anda adalah tautan simbolis, skrip tersebut akan memberi Anda jalur file yang ditautkannya (dan bukan jalur tautan simbolis).
sumber
Anda dapat menggunakan
Path
daripathlib
modul:Anda dapat menggunakan panggilan
parent
untuk melangkah lebih jauh di jalur:sumber
__file__
variabel yang bisa tidak dapat diandalkan (tidak selalu jalur file lengkap, tidak bekerja pada setiap sistem operasi, dll.) Seperti yang sering disebutkan oleh pengguna StackOverflow. Mengubah jawaban untuk tidak memasukkannya akan menyebabkan lebih sedikit masalah dan lebih kompatibel lintas. Untuk informasi lebih lanjut, lihat stackoverflow.com/a/33532002/3787376 .Jika kode berasal dari file, Anda bisa mendapatkan nama lengkapnya
Anda juga dapat mengambil nama fungsi sebagai
f_code.co_name
sumber
Cukup tambahkan berikut ini:
Atau:
sumber
Solusi saya adalah:
sumber
sumber
'__file__'
seharusnya bukan string, kedua, jika Anda melakukannya__file__
, ini hanya akan berfungsi untuk file tempat baris kode ini berada, dan bukan file yang dieksekusi?