Saya ingin mewarisi dari kelas dalam file yang terletak di direktori di atas yang sekarang.
Apakah mungkin untuk mengimpor file itu secara relatif?
sumber
Saya ingin mewarisi dari kelas dalam file yang terletak di direktori di atas yang sekarang.
Apakah mungkin untuk mengimpor file itu secara relatif?
from ..subpkg2 import mod
Per dokumen Python: Saat berada di dalam hierarki paket, gunakan dua titik, seperti yang dikatakan oleh dokumen pernyataan impor :
Saat menentukan modul apa yang akan diimpor, Anda tidak perlu menentukan nama absolut modul. Ketika modul atau paket terkandung dalam paket lain, dimungkinkan untuk melakukan impor relatif dalam paket teratas yang sama tanpa harus menyebutkan nama paket. Dengan menggunakan titik utama dalam modul atau paket yang ditentukan setelah
from
Anda dapat menentukan seberapa tinggi untuk melintasi hierarki paket saat ini tanpa menentukan nama yang tepat. Satu titik terkemuka berarti paket saat ini di mana modul membuat impor ada. Dua titik berarti naik satu tingkat paket . Tiga titik naik dua tingkat, dll. Jadi jika Anda mengeksekusifrom . import mod
dari modul dalampkg
paket maka Anda akan berakhir mengimporpkg.mod
. Jika Anda mengeksekusi . Spesifikasi untuk impor relatif terdapat di dalamnyafrom ..subpkg2 import mod
dari dalam,pkg.subpkg1
Anda akan mengimporpkg.subpkg2.mod
PEP 328 .
PEP 328 berkaitan dengan impor absolut / relatif.
sumber
Jawaban @ gimel benar jika Anda dapat menjamin hierarki paket yang ia sebutkan. Jika Anda tidak bisa - jika kebutuhan nyata Anda adalah seperti yang Anda ungkapkan, secara eksklusif terkait dengan direktori dan tanpa hubungan yang perlu dengan pengemasan - maka Anda perlu bekerja
__file__
untuk mengetahui direktori induk (beberapaos.path.dirname
panggilan akan dilakukan; -), maka (jika direktori yang tidak sudah disys.path
) tambahkan sementara insert mengatakan dir di bagian paling mulai darisys.path
,__import__
, menghapus kata dir lagi - pekerjaan berantakan memang, tapi, "ketika Anda harus, Anda harus" (dan kemudian berusaha Pyhon untuk jangan pernah menghentikan programmer dari melakukan apa yang harus dilakukan - seperti standar ISO C mengatakan di bagian "Spirit of C" di kata pengantar! -).Berikut ini contoh yang mungkin cocok untuk Anda:
sumber
sys.path
sehingga membuat modul yang sama tersedia dengan nama yang berbeda dan semua bug yang sesuai. autopath.py di pypy atau _preamble.py di twisted menyelesaikannya dengan menggunakan kriteria pencarian yang mengidentifikasi paket tingkat atas sambil melintasi direktori ke atas.sys.path.remove(pathYouJustAdded)
setelah impor yang Anda butuhkan agar tidak mempertahankan jalur baru ini.Impor modul dari direktori yang persis satu tingkat di atas direktori saat ini:
sumber
from .. import module
saya mendapat error ValueError: Mencoba impor relatif dalam non-paket dengan mengikuti rekomendasiCara memuat modul yang merupakan direktori
kata pengantar: Saya melakukan penulisan ulang substansial dari jawaban sebelumnya dengan harapan membantu memudahkan orang ke dalam ekosistem python, dan mudah-mudahan memberi setiap orang perubahan sukses terbaik dengan sistem impor python.
Ini akan mencakup impor relatif dalam satu paket , yang menurut saya merupakan kasus yang paling memungkinkan untuk pertanyaan OP.
Python adalah sistem modular
Inilah sebabnya kami menulis
import foo
untuk memuat modul "foo" dari root namespace, alih-alih menulis:Python tidak digabungkan ke sistem file
Inilah sebabnya mengapa kita dapat menanamkan python di lingkungan di mana tidak ada sistem file defacto tanpa menyediakan yang virtual, seperti Jython.
Karena dipisahkan dari sistem file memungkinkan impor menjadi fleksibel, desain ini memungkinkan untuk hal-hal seperti impor dari arsip / file zip, impor singleton, caching bytecode, ekstensi cffi, bahkan pemuatan definisi kode jarak jauh.
Jadi jika impor tidak digabungkan ke sistem file, apa artinya "satu direktori"? Kita harus memilih beberapa heuristik tetapi kita bisa melakukan itu, misalnya ketika bekerja di dalam suatu paket , beberapa heuristik telah didefinisikan yang membuat impor relatif suka
.foo
dan..foo
bekerja dalam paket yang sama. Keren!Jika Anda sungguh-sungguh ingin memasangkan pola pemuatan kode sumber Anda ke sistem file, Anda dapat melakukannya. Anda harus memilih heuristik Anda sendiri, dan menggunakan beberapa jenis mesin impor, saya sarankan importlib
Contoh importlib Python terlihat seperti ini:
Pengemasan
Ada contoh proyek bagus yang tersedia secara resmi di sini: https://github.com/pypa/sampleproject
Paket python adalah kumpulan informasi tentang kode sumber Anda, yang dapat memberi tahu alat lain cara menyalin kode sumber Anda ke komputer lain, dan cara mengintegrasikan kode sumber Anda ke jalur sistem itu sehingga
import foo
bekerja untuk komputer lain (terlepas dari penerjemah, sistem operasi host, dll)Struktur Direktori
Mari kita memiliki nama paket
foo
, di beberapa direktori (lebih disukai direktori kosong).Preferensi saya adalah membuat
setup.py
sebagai saudarafoo.py
, karena membuat menulis file setup.py lebih sederhana, namun Anda dapat menulis konfigurasi untuk mengubah / mengarahkan ulang semua yang dilakukan setuptools secara default jika Anda mau; misalnya meletakkan difoo.py
bawah direktori "src /" agak populer, tidak dibahas di sini..
.
"dapat diedit" alias
-e
akan mengarahkan kembali mesin pengimpor untuk memuat file sumber dalam direktori ini, alih-alih menyalin file yang sekarang aktif ke pustaka lingkungan pemasangan. Ini juga dapat menyebabkan perbedaan perilaku pada mesin pengembang, pastikan untuk menguji kode Anda! Ada alat selain pip, namun saya akan merekomendasikan pip menjadi pengantar :)Saya juga suka membuat
foo
"paket" (direktori berisi__init__.py
) alih-alih modul (file ".py" tunggal), baik "paket" dan "modul" dapat dimuat ke root namespace, modul memungkinkan ruang nama bersarang, yang sangat membantu jika kita ingin mengimpor "relatif satu direktori"..
Saya juga suka membuat
foo/__main__.py
, ini memungkinkan python untuk mengeksekusi paket sebagai modul, mis.python3 -m foo
Akan dieksekusifoo/__main__.py
sebagai__main__
..
Mari kita selesaikan ini dengan beberapa modul lagi: Pada dasarnya, Anda dapat memiliki struktur direktori seperti ini:
setup.py
secara konvensional menyimpan informasi metadata tentang kode sumber di dalamnya, seperti:foo
, meskipun mengganti garis bawah untuk tanda hubung sangat populerpython ./setup.py test
Sangat ekspansif, bahkan dapat mengkompilasi ekstensi c on the fly jika modul sumber sedang diinstal pada mesin pengembangan. Untuk contoh setiap hari, saya sarankan setup.py PYPA Sample Repository
Jika Anda merilis artefak build, misalnya salinan kode yang dimaksudkan untuk menjalankan komputer yang hampir identik, file requirement.txt adalah cara populer untuk mengambil snapshot informasi dependensi yang tepat, di mana "install_requires" adalah cara yang baik untuk menangkap minimum dan versi kompatibel maksimum. Namun, mengingat bahwa mesin target hampir identik, saya sangat merekomendasikan membuat tarball dari seluruh awalan python. Ini bisa rumit, terlalu rinci untuk masuk ke sini. Periksa
pip install
's--target
pilihan, atau virtualenv alias venv untuk memimpin.kembali ke contoh
cara mengimpor file satu direktori ke atas:
Dari foo / spam / eggs.py, jika kita menginginkan kode dari foo / baz kita bisa memintanya dengan namespace absolutnya:
Jika kami ingin menyimpan kapabilitas untuk memindahkan eggs.py ke beberapa direktori lain di masa mendatang dengan beberapa
baz
implementasi relatif lainnya , kami dapat menggunakan impor relatif seperti:sumber
Python adalah sistem modular
Python tidak bergantung pada sistem file
Untuk memuat kode python dengan andal, masukkan kode itu ke dalam modul, dan modul itu dipasang di pustaka python.
Modul yang diinstal selalu dapat dimuat dari namespace tingkat atas dengan
import <name>
Ada proyek contoh hebat yang tersedia secara resmi di sini: https://github.com/pypa/sampleproject
Pada dasarnya, Anda dapat memiliki struktur direktori seperti ini:
.
Pastikan untuk menyatakan
setuptools.setup()
di Andasetup.py
,contoh resmi: https://github.com/pypa/sampleproject/blob/master/setup.py
Dalam kasus kami, kami mungkin ingin mengekspor
bar.py
danfoo/__init__.py
, contoh singkat saya:setup.py
.
Sekarang kita dapat menginstal modul kita ke pustaka python; dengan pip, Anda dapat menginstal
the_foo_project
ke pustaka python Anda dalam mode edit, sehingga kami dapat bekerja secara real time.
Sekarang dari konteks python apa pun, kita dapat memuat py_modules dan paket bersama kita
foo_script.py
sumber
pip install --edit foo
, hampir selalu di dalam virtualenv. Saya hampir tidak pernah menulis modul yang tidak dimaksudkan untuk diinstal. jika saya salah mengerti sesuatu yang ingin saya ketahui.editable
tautan telur dan modul python yang dipasang tidak persis sama dalam segala hal; misalnya, menambahkan namespace baru ke modul yang dapat diedit akan ditemukan di pencarian path Anda, tetapi jika itu tidak diekspor dalam file setup.py Anda tidak akan dikemas / diinstal! Uji kasus penggunaan Anda :)