Tampaknya mereka membatalkan dengan Python 3 semua cara mudah untuk dengan cepat memuat skrip dengan menghapus execfile()
Apakah ada alternatif yang jelas saya lewatkan?
Tampaknya mereka membatalkan dengan Python 3 semua cara mudah untuk dengan cepat memuat skrip dengan menghapus execfile()
Apakah ada alternatif yang jelas saya lewatkan?
reload
kembali, karenaimp.reload
, sejak 3.2.%run script_name
berfungsi dengan semua versi Python.imp
adalahimportlib
(yang harus diimpor):importlib.reload(mod_name)
impor dan dijalankanmod_name
.runfile()
karena saya perlu menjalankan skrip Python yang dieksekusi di namespace sendiri (sebagai lawan mengeksekusi di namespace panggilan ). Aplikasi saya: tambahkan direktori skrip yang dipanggil ke jalur sistem (sys.path
) menggunakan__file__
atribut: jika kita menggunakanexecfile()
atau yang setara dengan Python 3 (exec(open('file.py').read())
) skrip yang disertakan dijalankan di namespace panggilan dan dengan demikian__file__
memutuskan untuk nama file panggilan .Jawaban:
Menurut dokumentasi , bukan
Menggunakan
Lihat:
sumber
close
menangani file itu juga. Alasan lain untuk tidak menyukai perubahan dari python 2.Anda hanya harus membaca file dan mengeksekusi kode sendiri. 2to3 diganti saat ini
sebagai
(Panggilan kompilasi tidak sepenuhnya diperlukan, tetapi menghubungkan nama file dengan objek kode yang membuat proses debug sedikit lebih mudah.)
Lihat:
sumber
exec
pernyataan dalam python2,exec(code)
berfungsi karena parens diabaikan."somefile.py"
terkandunginspect.getsourcefile(lambda _: None)
yang gagal tanpa kompilasi, karenainspect
modul tidak bisa menentukan di mana kode itu berasal.open("somefile.py")
mungkin salah jikasomefile.py
menggunakan pengkodean karakter berbeda darilocale.getpreferredencoding()
.tokenize.open()
bisa digunakan sebagai gantinya.Meskipun
exec(open("filename").read())
sering diberikan sebagai alternatifexecfile("filename")
, ia melewatkan detail penting yangexecfile
didukung.Fungsi berikut untuk Python3.x sedekat saya bisa memiliki perilaku yang sama seperti mengeksekusi file secara langsung. Itu cocok berjalan
python /path/to/somefile.py
.Catatan:
__main__
, beberapa skrip bergantung pada ini untuk memeriksa apakah mereka memuat sebagai modul atau bukan untuk mis.if __name__ == "__main__"
__file__
lebih baik untuk pesan pengecualian dan beberapa skrip digunakan__file__
untuk mendapatkan jalur file lain relatif terhadap mereka.Mengambil argumen global & lokal opsional, memodifikasi mereka di tempat seperti
execfile
halnya - sehingga Anda dapat mengakses variabel apa pun yang ditentukan dengan membaca kembali variabel setelah berjalan.Tidak seperti Python2,
execfile
ini tidak mengubah namespace saat ini secara default. Untuk itu Anda harus secara eksplisit memasukkanglobals()
&locals()
.sumber
Seperti yang disarankan pada milis python-dev baru-baru ini, modul runpy mungkin menjadi alternatif yang layak. Mengutip dari pesan itu:
Ada perbedaan halus untuk
execfile
:run_path
selalu menciptakan namespace baru. Ini mengeksekusi kode sebagai modul, sehingga tidak ada perbedaan antara global dan lokal (itulah sebabnya hanya adainit_globals
argumen). Global dikembalikan.execfile
dieksekusi di namespace saat ini atau namespace yang diberikan. Semantiklocals
danglobals
, jika diberikan, mirip dengan penduduk lokal dan global dalam definisi kelas.run_path
tidak hanya dapat mengeksekusi file, tetapi juga telur dan direktori (lihat dokumentasi untuk detailnya).sumber
file_globals
? Ini akan menghemat keharusan mengetikkanfile_globals['...']
untuk setiap variabel.Yang ini lebih baik, karena mengambil global dan penduduk lokal dari penelepon:
sumber
execfile
. Itu bahkan berfungsi untuk saya ketika menggunakan pytests di mana solusi lain yang diposting di atas gagal. Terima kasih! :)Anda dapat menulis fungsi Anda sendiri:
Jika Anda benar-benar perlu ...
sumber
globals
danlocals
menunjuk ke namespace global untuk modul yang berisi definisiexecfile()
daripada ke namespace global dan lokal penelepon. Pendekatan yang benar adalah dengan menggunakanNone
sebagai nilai default dan menentukan global penelepon dan penduduk setempat melalui kemampuan introspeksiinspect
modul.Jika skrip yang ingin Anda muat berada di direktori yang sama dengan yang Anda jalankan, mungkin "impor" akan melakukan tugasnya?
Jika Anda perlu mengimpor kode secara dinamis, fungsi bawaan __ import__ dan modul imp patut dilihat.
test.py:
Jika Anda menggunakan Python 3.1 atau lebih baru, Anda juga harus melihat importlib .
sumber
importlib
dev.to/0xcrypto/dynamic-importing-stuff-in-python--1805Inilah yang saya miliki (
file
sudah ditugaskan ke jalur ke file dengan kode sumber di kedua contoh):Inilah yang saya gantikan dengan:
Bagian favorit saya: versi kedua berfungsi dengan baik di Python 2 dan 3, artinya tidak perlu menambahkan logika versi dependen.
sumber
Perhatikan bahwa pola di atas akan gagal jika Anda menggunakan deklarasi pengkodean PEP-263 yang bukan ascii atau utf-8. Anda perlu menemukan penyandian data, dan menyandikannya dengan benar sebelum menyerahkannya ke exec ().
sumber
Selain itu, walaupun bukan solusi Python murni, jika Anda menggunakan IPython (seperti yang seharusnya Anda lakukan), Anda dapat melakukannya:
Yang sama mudahnya.
sumber
Saya hanya seorang pemula di sini jadi mungkin itu keberuntungan jika saya menemukan ini:
Setelah mencoba menjalankan skrip dari prompt interpreter >>> dengan perintah
di mana saya mendapat "NameError: name 'execfile' tidak didefinisikan" Saya mencoba yang sangat mendasar
itu bekerja dengan baik :-)
Saya harap ini bisa membantu dan terima kasih atas petunjuk, contoh, dan semua potongan kode yang dikomentari dengan hebat yang merupakan inspirasi hebat bagi pendatang baru!
Saya menggunakan Ubuntu 16.014 LTS x64. Python 3.5.2 (default, 17 Nov 2016, 17:05:23) [GCC 5.4.0 20160609] di linux
sumber
Bagi saya, pendekatan terbersih adalah menggunakan
importlib
dan mengimpor file sebagai modul dengan jalur, seperti:Contoh penggunaan
Mari kita punya file
foo.py
:Sekarang cukup impor dan gunakan seperti modul normal:
Saya lebih suka teknik ini daripada pendekatan langsung seperti
exec(open(...))
karena tidak mengacaukan ruang nama Anda atau mengacaukan yang tidak perlu$PATH
.sumber