Đã sử dụng các gói phẳng, tôi không mong đợi sự cố mà tôi gặp phải với các gói lồng nhau. Đây là…
Bố cục thư mục
dir
|
+-- test.py
|
+-- package
|
+-- __init__.py
|
+-- subpackage
|
+-- __init__.py
|
+-- module.py
Nội dung của init .py
Cả hai package/__init__.py
và package/subpackage/__init__.py
đều trống rỗng.
Nội dung của module.py
# file `package/subpackage/module.py`
attribute1 = "value 1"
attribute2 = "value 2"
attribute3 = "value 3"
# and as many more as you want...
Nội dung của test.py
(3 phiên bản)
Phiên bản 1
# file test.py
from package.subpackage.module import *
print attribute1 # OK
Đó là cách nhập hàng không tốt và không an toàn (nhập hàng loạt), nhưng nó hoạt động.
Phiên bản 2
# file test.py
import package.subpackage.module
from package.subpackage import module # Alternative
from module import attribute1
Một cách an toàn hơn để nhập, từng mục, nhưng không thành công, Python không muốn điều này: thất bại với thông báo: "Không có mô-đun nào có tên là mô-đun". Tuy nhiên …
# file test.py
import package.subpackage.module
from package.subpackage import module # Alternative
print module # Surprise here
… Nói <module 'package.subpackage.module' from '...'>
. Vì vậy, đó là một mô-đun, nhưng đó không phải là một mô-đun / -P 8-O ... uh
Phiên bản 3
# file test.py v3
from package.subpackage.module import attribute1
print attribute1 # OK
Cái này hoạt động. Vì vậy, bạn bị buộc phải sử dụng tiền tố quá mức cần thiết mọi lúc hoặc sử dụng cách không an toàn như trong phiên bản # 1 và Python không cho phép sử dụng cách tiện dụng an toàn? Cách tốt hơn, an toàn và tránh tiền tố dài không cần thiết là cách duy nhất mà Python từ chối? Điều này là do nó yêu thích import *
hay vì nó yêu thích các tiền tố quá dài (điều này không giúp ích gì cho việc thực thi phương pháp này) ?.
Xin lỗi vì những lời khó nghe, nhưng đó là hai ngày tôi cố gắng giải quyết hành vi giống như ngu ngốc này. Trừ khi tôi hoàn toàn sai ở đâu đó, điều này sẽ khiến tôi cảm thấy có gì đó thực sự bị hỏng trong mô hình gói và gói phụ của Python.
Ghi chú
- Tôi không muốn dựa vào
sys.path
, để tránh các tác dụng phụ trên toàn cầu, cũng như trên*.pth
các tệp, đó chỉ là một cách khác để chơi vớisys.path
cùng một hiệu ứng toàn cầu. Để dung dịch được sạch, nó chỉ được dùng tại chỗ. Python có thể xử lý gói con, hoặc không, nhưng nó không yêu cầu phải chơi với cấu hình toàn cục để có thể xử lý nội dung cục bộ. - Tôi cũng đã thử sử dụng nhập khẩu trong
package/subpackage/__init__.py
, nhưng nó không giải quyết được gì, nó vẫn hoạt động tương tự và phàn nànsubpackage
không phải là một mô-đun đã biết, trong khiprint subpackage
nói rằng đó là một mô-đun (hành vi kỳ lạ, một lần nữa).
Có thể tôi hoàn toàn sai lầm khi khó khăn (tùy chọn tôi thích hơn), nhưng điều này khiến tôi cảm thấy rất thất vọng về Python.
Bất kỳ cách nào khác được biết đến bên cạnh ba cách mà tôi đã thử? Một cái gì đó tôi không biết về?
(thở dài)
-----% <----- chỉnh sửa ----->% -----
Kết luận cho đến nay (sau ý kiến của mọi người)
Không có gì giống như gói phụ thực sự trong Python, vì tất cả các tham chiếu gói chỉ chuyển đến một phân đoạn toàn cục, điều đó có nghĩa là không có từ điển cục bộ, có nghĩa là không có cách nào để quản lý tham chiếu gói cục bộ.
Bạn phải sử dụng tiền tố đầy đủ hoặc tiền tố ngắn hoặc bí danh. Như trong:
Phiên bản tiền tố đầy đủ
from package.subpackage.module import attribute1
# An repeat it again an again
# But after that, you can simply:
use_of (attribute1)
Phiên bản tiền tố ngắn (nhưng tiền tố lặp lại)
from package.subpackage import module
# Short but then you have to do:
use_of (module.attribute1)
# and repeat the prefix at every use place
Hoặc nếu không, một biến thể của ở trên.
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
Phiên bản cơ sở hóa
Nếu bạn không phiền về việc nhập nhiều thực thể cùng một lúc trong một lô, bạn có thể:
from package.subpackage.module import attribute1, attribute2
# and etc.
Không phải trong khẩu vị yêu thích đầu tiên của tôi (tôi thích có một bảng sao kê nhập khẩu cho mỗi thực thể nhập khẩu), nhưng có thể là hương vị cá nhân tôi sẽ thích.
Cập nhật (2012-09-14):
Cuối cùng có vẻ là OK trong thực tế, ngoại trừ một nhận xét về bố cục. Thay vì ở trên, tôi đã sử dụng:
from package.subpackage.module import (
attribute1,
attribute2,
attribute3,
...) # and etc.