Setelah menggunakan paket datar, saya tidak mengharapkan masalah yang saya temui dengan paket bersarang. Disini adalah…
Tata letak direktori
dir
|
+-- test.py
|
+-- package
|
+-- __init__.py
|
+-- subpackage
|
+-- __init__.py
|
+-- module.py
Isi init .py
Keduanya package/__init__.py
dan package/subpackage/__init__.py
kosong.
Isi dari module.py
# file `package/subpackage/module.py`
attribute1 = "value 1"
attribute2 = "value 2"
attribute3 = "value 3"
# and as many more as you want...
Isi dari test.py
(3 versi)
Versi 1
# file test.py
from package.subpackage.module import *
print attribute1 # OK
Itu cara yang buruk dan tidak aman untuk mengimpor barang (impor semua dalam jumlah besar), tetapi berhasil.
Versi 2
# file test.py
import package.subpackage.module
from package.subpackage import module # Alternative
from module import attribute1
Cara yang lebih aman untuk mengimpor, item demi item, tetapi gagal, Python tidak menginginkan ini: gagal dengan pesan: "No module bernama module". Namun…
# file test.py
import package.subpackage.module
from package.subpackage import module # Alternative
print module # Surprise here
… Berkata <module 'package.subpackage.module' from '...'>
. Jadi itu modul, tapi itu bukan modul / -P 8-O ... uh
Versi 3
# file test.py v3
from package.subpackage.module import attribute1
print attribute1 # OK
Yang ini berhasil. Jadi Anda terpaksa menggunakan awalan yang berlebihan sepanjang waktu atau menggunakan cara yang tidak aman seperti pada versi # 1 dan tidak diizinkan oleh Python untuk menggunakan cara praktis yang aman? Cara yang lebih baik, mana yang aman dan menghindari awalan panjang yang tidak perlu adalah satu-satunya yang ditolak Python? Apakah ini karena cinta import *
atau karena menyukai prefiks yang terlalu panjang (yang tidak membantu untuk menegakkan praktik ini)?
Maaf untuk kata-kata sulitnya, tapi itu dua hari saya mencoba untuk mengatasi perilaku bodoh ini. Kecuali jika saya benar-benar salah, ini akan membuat saya merasa ada sesuatu yang benar-benar rusak dalam model paket dan sub-paket Python.
Catatan
- Saya tidak ingin mengandalkan
sys.path
, untuk menghindari efek samping global, atau*.pth
file, yang hanya merupakan cara lain untuk bermainsys.path
dengan efek global yang sama. Agar solusinya bersih, harus lokal saja. Entah Python dapat menangani sub-paket, baik itu tidak, tetapi tidak perlu bermain dengan konfigurasi global untuk dapat menangani barang-barang lokal. - Saya juga mencoba menggunakan impor
package/subpackage/__init__.py
, tetapi tidak menyelesaikan apa-apa, melakukan hal yang sama, dan komplainsubpackage
bukan modul yang dikenal, sementaraprint subpackage
mengatakan ini adalah modul (perilaku aneh, sekali lagi).
Mungkin saya sepenuhnya salah tangguh (opsi yang saya lebih suka), tetapi ini membuat saya merasa sangat kecewa dengan Python.
Adakah cara lain yang diketahui selain dari ketiganya yang saya coba? Sesuatu yang tidak saya ketahui?
(mendesah)
-----% <----- edit ----->% -----
Kesimpulan sejauh ini (setelah komentar orang)
Tidak ada sub-paket nyata dalam Python, karena semua referensi paket hanya masuk ke kamus global, yang berarti tidak ada kamus lokal, yang berarti tidak ada cara untuk mengelola referensi paket lokal.
Anda harus menggunakan prefiks penuh atau prefiks pendek atau alias. Seperti dalam:
Versi awalan lengkap
from package.subpackage.module import attribute1
# An repeat it again an again
# But after that, you can simply:
use_of (attribute1)
Versi awalan pendek (tapi awalan berulang)
from package.subpackage import module
# Short but then you have to do:
use_of (module.attribute1)
# and repeat the prefix at every use place
Atau, variasi di atas.
from package.subpackage import module as m
use_of (m.attribute1)
# `m` is a shorter prefix, but you could as well
# define a more meaningful name after the context
Versi terfaktor
Jika Anda tidak keberatan mengimpor beberapa entitas sekaligus dalam satu batch, Anda dapat:
from package.subpackage.module import attribute1, attribute2
# and etc.
Tidak dalam rasa favorit pertama saya (saya lebih suka memiliki satu pernyataan impor per entitas yang diimpor), tetapi mungkin yang saya sukai secara pribadi.
Pembaruan (2012-09-14):
Akhirnya tampaknya OK dalam praktiknya, kecuali dengan komentar tentang tata letak. Alih-alih di atas, saya menggunakan:
from package.subpackage.module import (
attribute1,
attribute2,
attribute3,
...) # and etc.