หลังจากใช้แพ็กเกจแบบแบนแล้วฉันไม่ได้คาดหวังว่าจะพบปัญหากับแพ็กเกจที่ซ้อนกัน ที่นี่คือ…
เค้าโครงไดเรกทอรี
dir
|
+-- test.py
|
+-- package
|
+-- __init__.py
|
+-- subpackage
|
+-- __init__.py
|
+-- module.py
เนื้อหาของinit .py
ทั้งสองpackage/__init__.py
และpackage/subpackage/__init__.py
ว่างเปล่า
เนื้อหาของ module.py
# file `package/subpackage/module.py`
attribute1 = "value 1"
attribute2 = "value 2"
attribute3 = "value 3"
# and as many more as you want...
เนื้อหาของtest.py
(3 เวอร์ชัน)
เวอร์ชัน 1
# file test.py
from package.subpackage.module import *
print attribute1 # OK
นั่นเป็นวิธีการนำเข้าที่ไม่ดีและไม่ปลอดภัย (นำเข้าทั้งหมดในจำนวนมาก) แต่ได้ผล
เวอร์ชัน 2
# file test.py
import package.subpackage.module
from package.subpackage import module # Alternative
from module import attribute1
วิธีที่ปลอดภัยกว่าในการนำเข้าทีละรายการ แต่ล้มเหลว Python ไม่ต้องการสิ่งนี้: ล้มเหลวด้วยข้อความ: "No module named module" อย่างไรก็ตาม…
# file test.py
import package.subpackage.module
from package.subpackage import module # Alternative
print module # Surprise here
…พูดว่า<module 'package.subpackage.module' from '...'>
. นั่นคือโมดูล แต่นั่นไม่ใช่โมดูล / -P 8-O ... เอ่อ
เวอร์ชัน 3
# file test.py v3
from package.subpackage.module import attribute1
print attribute1 # OK
อันนี้ใช้ได้เลย ดังนั้นคุณอาจถูกบังคับให้ใช้คำนำหน้า overkill ตลอดเวลาหรือใช้วิธีที่ไม่ปลอดภัยเหมือนในเวอร์ชัน # 1 และ Python ไม่อนุญาตให้ใช้วิธีที่ปลอดภัยหรือไม่? วิธีที่ดีกว่าซึ่งปลอดภัยและหลีกเลี่ยงคำนำหน้าแบบยาวที่ไม่จำเป็นคือสิ่งเดียวที่ Python ปฏิเสธ? นี่เป็นเพราะมันรักimport *
หรือเพราะมันชอบคำนำหน้ามากเกินไป (ซึ่งไม่ได้ช่วยในการบังคับใช้การปฏิบัตินี้)?
ขอโทษสำหรับคำพูดที่ยาก แต่นั่นเป็นสองวันที่ฉันพยายามแก้ไขพฤติกรรมโง่ ๆ แบบนี้ ถ้าฉันไม่ได้ทำผิดที่ใดที่หนึ่งโดยสิ้นเชิงสิ่งนี้จะทำให้ฉันรู้สึกว่ามีบางอย่างที่ผิดปกติในโมเดลแพ็คเกจและแพ็คเกจย่อยของ Python
หมายเหตุ
- ฉันไม่ต้องการพึ่งพา
sys.path
เพื่อหลีกเลี่ยงผลข้างเคียงระดับโลกหรือใน*.pth
ไฟล์ซึ่งเป็นอีกวิธีหนึ่งในการเล่นsys.path
กับผลกระทบระดับโลกเดียวกัน สำหรับวิธีการแก้ปัญหาที่สะอาดจะต้องมีเฉพาะในท้องถิ่นเท่านั้น Python ทั้งสองตัวสามารถจัดการกับแพ็กเกจย่อยได้หรือไม่ แต่ก็ไม่ควรเล่นกับการกำหนดค่าส่วนกลางเพื่อให้สามารถจัดการกับสิ่งต่างๆในเครื่องได้ - ฉันลองใช้การนำเข้า
package/subpackage/__init__.py
ด้วย แต่มันไม่ได้แก้ไขอะไรเลยมันทำเหมือนเดิมและบ่นว่าsubpackage
ไม่ใช่โมดูลที่รู้จักในขณะที่print subpackage
บอกว่าเป็นโมดูล (พฤติกรรมแปลก ๆ อีกแล้ว)
อาจเป็นเพราะฉันคิดผิดอย่างสิ้นเชิง (ตัวเลือกที่ฉันต้องการ) แต่สิ่งนี้ทำให้ฉันรู้สึกผิดหวังมากเกี่ยวกับ Python
วิธีอื่นที่เป็นที่รู้จักนอกเหนือจากทั้งสามที่ฉันลอง? บางสิ่งที่ฉันไม่รู้เกี่ยวกับ?
(ถอนหายใจ)
-----% <----- แก้ไข ----->% -----
สรุปแล้ว (หลังจากความคิดเห็นของผู้คน)
ไม่มีอะไรที่เหมือนกับแพ็กเกจย่อยจริงใน Python เนื่องจากการอ้างอิงแพ็คเกจทั้งหมดไปที่พจนานุกรมทั่วโลกเท่านั้นซึ่งหมายความว่าไม่มีพจนานุกรมในเครื่องซึ่งหมายความว่าไม่มีวิธีจัดการการอ้างอิงแพ็กเกจในเครื่อง
คุณต้องใช้คำนำหน้าแบบเต็มหรือคำนำหน้าแบบสั้นหรือนามแฝง ใน:
คำนำหน้าเวอร์ชันเต็ม
from package.subpackage.module import attribute1
# An repeat it again an again
# But after that, you can simply:
use_of (attribute1)
คำนำหน้าแบบสั้น (แต่คำนำหน้าซ้ำ)
from package.subpackage import module
# Short but then you have to do:
use_of (module.attribute1)
# and repeat the prefix at every use place
หรือรูปแบบอื่น ๆ ข้างต้น
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
รุ่นแยกตัวประกอบ
หากคุณไม่ทราบเกี่ยวกับการนำเข้าหลายเอนทิตีพร้อมกันในชุดงานคุณสามารถ:
from package.subpackage.module import attribute1, attribute2
# and etc.
ไม่ใช่รสชาติที่ฉันชอบเป็นอันดับแรก (ฉันชอบที่จะมีใบแจ้งยอดการนำเข้าหนึ่งรายการต่อหน่วยงานที่นำเข้า) แต่อาจเป็นสิ่งที่ฉันชอบเป็นการส่วนตัว
ปรับปรุง (2012-09-14):
ในที่สุดดูเหมือนจะใช้ได้ในทางปฏิบัติยกเว้นมีความคิดเห็นเกี่ยวกับเค้าโครง แทนที่จะใช้ข้างต้นฉันใช้:
from package.subpackage.module import (
attribute1,
attribute2,
attribute3,
...) # and etc.