2011-12-17 34 views
5

Tôi tự hỏi tại sao thư mục (gói phụ) chứa mô-đun con trong gói python hiển thị dưới dạng biểu tượng khi gói được nhập. Ví dụ, nếu tôi có gói này:gói nhập python - gói phụ không được hiển thị trong biểu tượng bảng

PyModTest/      Top-level package 
      __init__.py    Initialize the package 
      Source/     Subpackage holding source files 
       __init__.py 
       WildMod.py  Submodule containing a function: 'WildFunc' 

nơi mức __init__.py đầu trông như thế này:

#!/usr/bin/env python 

from Source.WildMod import WildFunc 

và, cho đầy đủ vì lợi ích, các __init__.py cấp dưới trông như thế này :

#!/usr/bin/env python 

__all__ = ["WildMod"] 

OK, vì vậy bây giờ tôi mở ra người phiên dịch, nhập khẩu các mô-đun, và nhìn vào những biểu tượng:

>>> import PyModTest 
>>> dir(PyModTest) 
['Source', 'WildFunc', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__'] 

XEM, mô-đun 'Nguồn' hiển thị, mặc dù tôi chưa bao giờ nhập riêng nó!

Biểu tượng duy nhất (bên cạnh biểu tượng riêng tư) mà tôi muốn xem là 'WildFunc' của tôi. Có cách nào để ẩn gói 'Nguồn' không?

Trả lời

6

Hai điều cần lưu ý ở đây:

  • Trong Python, mô-đun đối tượng thực tế, và các chấm xuất hiện giữa tên của họ đại diện cho một truy cập thuộc tính thực tế
  • Bạn đang làm một nhập khẩu tương đối, có nghĩa là Source thực sự là PyModTest.Source (nhờ TokenMacGuy cho trỏ này ra)

vì vậy: để nhập PyModTest.Source.WildMod.WildFunc, Python phải

  1. nhập khẩu PyModTest (mà đã được thực hiện bởi bạn)
  2. kiểm tra và xem nếu nó có một thuộc tính gọi là Source, và nếu không, tạo ra các thuộc tính bằng cách nhập nó từ PyModTest/Source/__init__.py
  3. kiểm tra và thấy rằng nếu có một thuộc tính gọi là WildMod, và nếu không, tạo ra các thuộc tính bằng cách nhập nó từ PyModTest/Source/WildMod.py
  4. kiểm tra và thấy rằng nếu có một thuộc tính gọi là WildFunc (mà nó)

Một số chi tiết liên quan được thảo luận trong PEP 302 và trong Python language reference.

Sâu hơn trong cơ chế, nhập tên chấm chấm được chia nhỏ bởi thành phần của nó. Đối với "import spam.ham", trước hết là "import spam" là được thực hiện và chỉ khi thành công đó là "ham" được nhập dưới dạng mô-đun phụ của "spam".

Nếu bạn không muốn có biến có tên Source, thật dễ dàng để sửa chữa: chỉ del Source sau khi bạn nhập hàm. Nhưng lưu ý rằng nó sẽ ngăn chặn bất kỳ mã nào chạy sau này khi truy cập PyModTest.Source.<anything> (ngoại trừ WildFunc, vì bạn đã lưu tham chiếu đến điều đó).Tôi chắc chắn sẽ đề nghị chỉ bỏ qua các tài liệu tham khảo để Source, không xóa nó, vì nó không làm tổn thương bất cứ điều gì.

+0

Tuyệt vời, điều đó có ý nghĩa. Cảm ơn bạn đã gợi ý về 'del Source' :) – rokuingh

+2

'Source' là một gói con của' PyModTest', nhập ngầm sẽ được chuyển thành 'from PyModTest.Source import ...', và vì vậy mô-đun 'Source' phải được thêm vào như là một thuộc tính của mô-đun 'PyModTest'. Nếu 'Source' đã được tìm thấy bên ngoài gói' PyModTest' (có thể, các gói con được ưu tiên hơn 'sys.path'), điều này sẽ không xảy ra. Để tránh nhầm lẫn bản thân và người khác, luôn luôn thích nhập khẩu tuyệt đối. – SingleNegationElimination

+0

@TokenMacGuy: ah, bắt tốt. Bằng cách nào đó tôi đã bỏ lỡ thực tế rằng đây là một nhập khẩu tương đối. –

Các vấn đề liên quan