Bagaimana saya bisa memuat modul Python diberikan path lengkapnya? Perhatikan bahwa file tersebut dapat berada di mana saja di sistem file, karena ini merupakan opsi konfigurasi.
python
configuration
python-import
python-module
tercabut
sumber
sumber
Jawaban:
Untuk penggunaan Python 3.5+:
Untuk Python 3.3 dan 3.4 gunakan:
(Meskipun ini sudah usang dalam Python 3.4.)
Untuk Python 2 gunakan:
Ada fungsi kenyamanan yang setara untuk file Python dan DLL yang dikompilasi.
Lihat juga http://bugs.python.org/issue21436 .
sumber
__import__
.imp.load_source
hanya menetapkan.__name__
modul yang dikembalikan. itu tidak mempengaruhi pemuatan.imp.load_source()
menentukan kunci entri baru yang dibuat dalamsys.modules
kamus, sehingga argumen pertama memang mempengaruhi pemuatan.imp
modul ditinggalkan sejak versi 3.4: Theimp
paket tertunda bantahan mendukungimportlib
.Keuntungan menambahkan path ke sys.path (lebih dari menggunakan imp) adalah bahwa hal itu menyederhanakan hal-hal ketika mengimpor lebih dari satu modul dari satu paket. Sebagai contoh:
sumber
sys.path.append
untuk menunjuk ke file python tunggal, bukan direktori?importlib.import_module(mod_name)
dapat digunakan sebagai pengganti impor eksplisit di sini jika nama modul tidak dikenal saat runtime saya akan menambahkansys.path.pop()
pada akhirnya, meskipun, dengan asumsi kode yang diimpor tidak mencoba untuk mengimpor lebih banyak modul seperti yang digunakan.Jika modul tingkat atas Anda bukan file tetapi dikemas sebagai direktori dengan __init__.py, maka solusi yang diterima hampir berfungsi, tetapi tidak cukup. Dalam Python 3.5+ kode berikut diperlukan (perhatikan baris yang ditambahkan yang dimulai dengan 'sys.modules'):
Tanpa baris ini, ketika exec_module dijalankan, ia mencoba untuk mengikat impor relatif di __init__.py tingkat atas ke nama modul tingkat atas - dalam hal ini "mymodule". Tetapi "mymodule" belum dimuat sehingga Anda akan mendapatkan kesalahan "SystemError: Modul induk 'mymodule' tidak dimuat, tidak dapat melakukan impor relatif". Jadi, Anda harus mengikat nama sebelum memuatnya. Alasan untuk ini adalah invarian mendasar dari sistem impor relatif: "holding invarian adalah bahwa jika Anda memiliki sys.modules ['spam'] dan sys.modules ['spam.foo'] (seperti yang Anda lakukan setelah impor di atas ), yang terakhir harus muncul sebagai atribut foo dari yang sebelumnya " seperti yang dibahas di sini .
sumber
mymodule
?/path/to/your/module/
sebenarnya/path/to/your/PACKAGE/
? danmymodule
maksud Andamyfile.py
?Untuk mengimpor modul Anda, Anda perlu menambahkan direktori ke variabel lingkungan, baik sementara atau permanen.
Untuk sementara
Secara permanen
Menambahkan baris berikut ke
.bashrc
file Anda (di linux) dan jalankansource ~/.bashrc
di terminal:Credit / Source: saarrrr , pertanyaan lain tentang stackexchange
sumber
Sepertinya Anda tidak ingin mengimpor file konfigurasi secara khusus (yang memiliki banyak efek samping dan komplikasi tambahan), Anda hanya ingin menjalankannya, dan dapat mengakses namespace yang dihasilkan. Pustaka standar menyediakan API khusus untuk itu dalam bentuk runpy.run_path :
Antarmuka itu tersedia dalam Python 2.7 dan Python 3.2+
sumber
result[name]
,result.get('name', default_value)
, dll)from runpy import run_path; from argparse import Namespace; mod = Namespace(**run_path('path/to/file.py'))
Anda juga dapat melakukan sesuatu seperti ini dan menambahkan direktori tempat file konfigurasi berada di jalur memuat Python, dan kemudian hanya melakukan impor normal, dengan asumsi Anda tahu nama file di muka, dalam hal ini "config".
Berantakan, tetapi berhasil.
sumber
Anda dapat menggunakan
metode dari modul imp .
sumber
imp.load_dynamic(module_name, path_to_file)
untuk DLLsumber
except:
klausa catch-all jarang merupakan ide yang bagus.save_cwd = os.getcwd()
try: …
finally: os.chdir(save_cwd)
this is already addressed by the standard library
ya, tapi python memiliki kebiasaan buruk untuk tidak kompatibel ke belakang ... karena jawaban yang dicentang mengatakan ada 2 cara berbeda sebelum dan sesudah 3.3. Dalam hal ini saya lebih suka menulis fungsi universal saya sendiri daripada memeriksa versi dengan cepat. Dan ya, mungkin kode ini tidak terlindungi dengan baik dari kesalahan, tetapi ini menunjukkan sebuah ide (yaitu os.chdir (), saya belum memikirkannya), berdasarkan mana saya dapat menulis kode yang lebih baik. Karenanya +1.Berikut adalah beberapa kode yang berfungsi di semua versi Python, dari 2.7-3.5 dan bahkan mungkin yang lain.
Saya mengujinya. Mungkin jelek tapi sejauh ini adalah satu-satunya yang berfungsi di semua versi.
sumber
load_source
tidak karena mengimpor skrip dan memberikan akses skrip ke modul dan global pada saat mengimpor.Saya telah datang dengan versi yang sedikit dimodifikasi dari jawaban luar biasa @ SebastianRittau (untuk Python> 3,4 saya pikir), yang akan memungkinkan Anda untuk memuat file dengan ekstensi apa pun sebagai modul menggunakan
spec_from_loader
alih-alihspec_from_file_location
:Keuntungan dari pengkodean jalur secara eksplisit
SourceFileLoader
adalah bahwa mesin tidak akan mencoba mencari tahu jenis file dari ekstensi. Ini berarti bahwa Anda dapat memuat sesuatu seperti.txt
file menggunakan metode ini, tetapi Anda tidak dapat melakukannyaspec_from_file_location
tanpa menentukan loader karena.txt
tidak adaimportlib.machinery.SOURCE_SUFFIXES
.sumber
Apakah maksud Anda memuat atau mengimpor?
Anda dapat memanipulasi
sys.path
daftar menentukan jalur ke modul Anda, lalu mengimpor modul Anda. Misalnya, diberikan modul di:Anda bisa melakukannya:
sumber
sys.path[0:0] = ['/foo']
Explicit is better than implicit.
Jadi mengapa tidaksys.path.insert(0, ...)
bukansys.path[0:0]
?Saya yakin Anda bisa menggunakan
imp.find_module()
danimp.load_module()
memuat modul yang ditentukan. Anda harus memisahkan nama modul dari jalur, yaitu jika Anda ingin memuat,/home/mypath/mymodule.py
Anda harus melakukan:... tapi itu harus menyelesaikan pekerjaan.
sumber
Anda dapat menggunakan
pkgutil
modul (khususnyawalk_packages
metode) untuk mendapatkan daftar paket di direktori saat ini. Dari sana sepele untuk menggunakanimportlib
mesin untuk mengimpor modul yang Anda inginkan:sumber
Buat python module test.py
Buat modul python test_check.py
Kita dapat mengimpor modul yang diimpor dari modul.
sumber
Area Python 3.4 ini tampaknya sangat berliku untuk dipahami! Namun dengan sedikit peretasan menggunakan kode dari Chris Calloway sebagai permulaan saya berhasil membuat sesuatu bekerja. Inilah fungsi dasarnya.
Ini tampaknya menggunakan modul yang tidak usang dari Python 3.4. Saya tidak berpura-pura mengerti mengapa, tetapi tampaknya berhasil dari dalam suatu program. Saya menemukan solusi Chris bekerja pada baris perintah tetapi tidak dari dalam suatu program.
sumber
Saya tidak mengatakan bahwa itu lebih baik, tetapi demi kelengkapan, saya ingin menyarankan
exec
fungsi tersebut, tersedia dalam python 2 dan 3.exec
memungkinkan Anda untuk mengeksekusi kode arbitrer baik dalam lingkup global, atau dalam lingkup internal, disediakan sebagai kamus.Misalnya, jika Anda memiliki modul yang disimpan di
"/path/to/module
"dengan fungsifoo()
, Anda bisa menjalankannya dengan melakukan hal berikut:Ini membuatnya sedikit lebih eksplisit bahwa Anda memuat kode secara dinamis, dan memberi Anda kekuatan tambahan, seperti kemampuan untuk menyediakan builtin khusus.
Dan jika memiliki akses melalui atribut, alih-alih kunci penting bagi Anda, Anda dapat mendesain kelas dict khusus untuk global, yang menyediakan akses seperti itu, misalnya:
sumber
Untuk mengimpor modul dari nama file yang diberikan, Anda dapat memperpanjang sementara jalur, dan mengembalikan jalur sistem di referensi blok akhirnya :
sumber
Jika kami memiliki skrip dalam proyek yang sama tetapi dengan cara direktori yang berbeda, kami dapat menyelesaikan masalah ini dengan metode berikut.
Dalam situasi
utils.py
ini ada disrc/main/util/
sumber
Ini seharusnya bekerja
sumber
name, ext = os.path.splitext(os.path.basename(infile))
. Metode Anda berfungsi karena batasan sebelumnya untuk ekstensi .py. Juga, Anda mungkin harus mengimpor modul ke beberapa entri variabel / kamus.Saya membuat paket yang digunakan
imp
untuk Anda. Saya menyebutnyaimport_file
dan ini adalah bagaimana ini digunakan:Anda bisa mendapatkannya di:
http://pypi.python.org/pypi/import_file
atau di
http://code.google.com/p/import-file/
sumber
Impor modul paket saat runtime (resep Python)
http://code.activestate.com/recipes/223972/
sumber
Di Linux, menambahkan tautan simbolik di direktori skrip python Anda berfungsi.
yaitu:
python akan membuat
/absolute/path/to/script/module.pyc
dan akan memperbaruinya jika Anda mengubah konten/absolute/path/to/module/module.py
kemudian sertakan yang berikut ini di mypythonscript.py
sumber
git
dan memeriksa Andagit status
untuk memverifikasi bahwa perubahan Anda pada skrip benar-benar membuatnya kembali ke dokumen sumber dan tidak tersesat di eter.Saya telah menulis fungsi impor global dan portabel saya sendiri, berdasarkan
importlib
modul, untuk:sys.path
atau pada penyimpanan jalur pencarian apa pun.Struktur direktori contoh:
Ketergantungan dan keteraturan inklusi:
Penerapan:
Toko perubahan terbaru: https://sourceforge.net/p/tacklelib/tacklelib/HEAD/tree/trunk/python/tacklelib/tacklelib.py
test.py :
testlib.py :
testlib.std1.py :
testlib.std2.py :
testlib.std3.py :
Output (
3.7.4
):Diuji di Python
3.7.4
,3.2.5
,2.7.16
Pro :
testlib.std.py
sepertitestlib
,testlib.blabla.py
sepertitestlib_blabla
dan seterusnya).sys.path
atau pada penyimpanan jalur pencarian apa pun.SOURCE_FILE
danSOURCE_DIR
antar panggilan ketkl_import_module
.3.4.x
dan lebih tinggi] Dapat mencampur ruang nama modul dalamtkl_import_module
panggilan bersarang (mis:named->local->named
ataulocal->named->local
dan sebagainya).3.4.x
dan lebih tinggi] Dapat mengekspor variabel / fungsi / kelas global secara otomatis dari tempat dideklarasikan ke semua modul anak yang diimpor melaluitkl_import_module
(melaluitkl_declare_global
fungsi).Cons :
3.3.x
dan lebih rendah] Harus menyatakantkl_import_module
dalam semua modul yang membutuhkantkl_import_module
(duplikasi kode)Perbarui 1,2 (untuk
3.4.x
dan lebih tinggi):Dalam Python 3.4 dan lebih tinggi Anda dapat melewati persyaratan untuk mendeklarasikan
tkl_import_module
dalam setiap modul dengan mendeklarasikantkl_import_module
dalam modul tingkat atas dan fungsinya akan menyuntikkan dirinya sendiri ke semua modul anak-anak dalam satu panggilan (ini semacam impor self deploy).Perbarui 3 :
Menambahkan fungsi
tkl_source_module
sebagai analog ke bashsource
dengan penjaga eksekusi dukungan saat impor (diimplementasikan melalui penggabungan modul, bukan impor).Pembaruan 4 :
Fungsi yang ditambahkan
tkl_declare_global
untuk secara otomatis mengekspor variabel global modul ke semua modul anak-anak di mana variabel global modul tidak terlihat karena bukan merupakan bagian dari modul anak.Pembaruan 5 :
Semua fungsi telah pindah ke perpustakaan tacklelib, lihat tautan di atas.
sumber
Ada paket yang didedikasikan untuk ini secara khusus:
Ini diuji di versi Python (Jython dan PyPy juga), tetapi mungkin berlebihan tergantung pada ukuran proyek Anda.
sumber
Menambahkan ini ke daftar jawaban karena saya tidak dapat menemukan apa pun yang berfungsi. Ini akan memungkinkan impor modul python dikompilasi (pyd) di 3.4:
sumber
caranya cukup sederhana: misalkan Anda ingin mengimpor file dengan path relatif ../../MyLibs/pyfunc.py
Tetapi jika Anda berhasil tanpa penjaga Anda akhirnya bisa mendapatkan jalan yang sangat panjang
sumber
Solusi sederhana menggunakan
importlib
alih-alihimp
paket (diuji untuk Python 2.7, meskipun harus bekerja untuk Python 3 juga):Sekarang Anda dapat langsung menggunakan namespace dari modul yang diimpor, seperti ini:
Keuntungan dari solusi ini adalah kita bahkan tidak perlu tahu nama sebenarnya dari modul yang ingin kita impor , untuk menggunakannya dalam kode kita. Ini berguna, misalnya jika jalur modul adalah argumen yang dapat dikonfigurasi.
sumber
sys.path
, yang tidak cocok untuk setiap kasus penggunaan.sys.path.pop()
Jawaban ini adalah tambahan untuk jawaban Sebastian Rittau menanggapi komentar: "tetapi bagaimana jika Anda tidak memiliki nama modul?" Ini adalah cara cepat dan kotor untuk mendapatkan nama modul python yang mungkin diberikan nama file - hanya naik pohon sampai menemukan direktori tanpa
__init__.py
file dan kemudian mengubahnya kembali menjadi nama file. Untuk Python 3.4+ (menggunakan pathlib), yang masuk akal karena orang Py2 dapat menggunakan "imp" atau cara lain untuk melakukan impor relatif:Tentunya ada kemungkinan untuk peningkatan, dan
__init__.py
file-file opsional mungkin memerlukan perubahan lain, tetapi jika Anda memiliki__init__.py
secara umum, ini adalah triknya.sumber
Cara terbaik, saya pikir, adalah dari dokumentasi resmi ( 29.1. Imp - Akses internal impor ):
sumber