Zaten düz paketler kullandığım için iç içe paketlerle karşılaştığım sorunu beklemiyordum. Burada…
Dizin düzeni
dir
|
+-- test.py
|
+-- package
|
+-- __init__.py
|
+-- subpackage
|
+-- __init__.py
|
+-- module.py
İçeriği init .py
Hem package/__init__.py
ve package/subpackage/__init__.py
boş.
İçeriği module.py
# file `package/subpackage/module.py`
attribute1 = "value 1"
attribute2 = "value 2"
attribute3 = "value 3"
# and as many more as you want...
İçeriği test.py
(3 versiyon)
Versiyon 1
# file test.py
from package.subpackage.module import *
print attribute1 # OK
Bu, bir şeyleri içe aktarmanın kötü ve güvenli olmayan yolu (hepsini toplu olarak içe aktar), ancak işe yarıyor.
Versiyon 2
# file test.py
import package.subpackage.module
from package.subpackage import module # Alternative
from module import attribute1
Öğeye göre içe aktarmanın daha güvenli bir yolu, ancak başarısız oluyor, Python bunu istemiyor: "Modül adında modül yok" mesajıyla başarısız oluyor. Ancak …
# file test.py
import package.subpackage.module
from package.subpackage import module # Alternative
print module # Surprise here
… Diyor <module 'package.subpackage.module' from '...'>
. Yani bu bir modül, ama bu bir modül değil / -P 8-O ... uh
Sürüm 3
# file test.py v3
from package.subpackage.module import attribute1
print attribute1 # OK
Bu çalışıyor. Yani ya her zaman aşırı öldürme önekini kullanmak zorunda kalıyorsunuz ya da 1. sürümde olduğu gibi güvenli olmayan yolu kullanmak zorunda kalıyorsunuz ve Python tarafından güvenli ve kullanışlı yolu kullanmak için izin verilmiyor mu? Güvenli olan ve gereksiz uzun öneklerden kaçınmanın daha iyi yolu, Python'un reddettiği tek yol mu? Bu, sevdiği import *
için mi yoksa aşırı uzun önekleri sevdiği için mi?
Zor sözler için özür dilerim, ama bu iki gün bu aptalca davranışları aşmaya çalışıyorum. Bir yerde tamamen yanılmadıysam, bu bana Python'un paket ve alt paket modelinde bir şeylerin gerçekten bozuk olduğunu hissettirecek.
Notlar
sys.path
Küresel yan etkilerden kaçınmak için ya da*.pth
dosyalara güvenmek istemiyorum , bunlarsys.path
aynı küresel etkilerle oynamanın başka bir yolu . Çözümün temiz olması için yalnızca yerel olması gerekir. Her iki Python da alt paketi işleyebilir, ya da değil, ancak yerel şeyleri işleyebilmek için global konfigürasyonla oynamaya gerek kalmamalıdır.- Ayrıca ithalatı kullanmayı denedim
package/subpackage/__init__.py
, ama hiçbir şeyi çözmedi, aynı şeyi yapıyor ve şikayetçisubpackage
bir modül değil,print subpackage
bunun bir modül olduğunu söylüyor (yine garip davranış).
Tamamen yanılıyor olabilirim (tercih ettiğim seçenek), ama bu Python hakkında beni çok hayal kırıklığına uğratıyor.
Denediğim üçünün dışında bilinen başka bir yol var mı? Bilmediğim bir şey mi?
(iç çekmek)
-----% <----- düzenle ----->% -----
Şimdiye kadarki sonuç (insanların yorumlarından sonra)
Python'da gerçek alt paket gibisi yoktur, çünkü tüm paket referansları yalnızca küresel bir sözlüğe gider, bu da yerel bir sözlük olmadığı anlamına gelir, bu da yerel paket referansını yönetmenin bir yolu olmadığı anlamına gelir.
Tam önek veya kısa önek veya takma ad kullanmanız gerekir. De olduğu gibi:
Tam önek sürümü
from package.subpackage.module import attribute1
# An repeat it again an again
# But after that, you can simply:
use_of (attribute1)
Kısa önek versiyonu (ancak tekrarlanan önek)
from package.subpackage import module
# Short but then you have to do:
use_of (module.attribute1)
# and repeat the prefix at every use place
Ya da yukarıdakinin bir varyasyonu.
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
Faktörlü versiyon
Birden çok varlığı aynı anda toplu olarak içe aktarmayı düşünmüyorsanız şunları yapabilirsiniz:
from package.subpackage.module import attribute1, attribute2
# and etc.
İlk favori zevkimde değil (ithal edilen her varlık için bir ithalat beyannamesi olmasını tercih ederim), ancak kişisel olarak tercih edeceğim biri olabilir.
Güncelleme (2012-09-14):
Son olarak, düzen hakkında bir yorum dışında pratikte iyi görünüyor. Yukarıdakilerin yerine kullandım:
from package.subpackage.module import (
attribute1,
attribute2,
attribute3,
...) # and etc.