2013-03-06 32 views
5

Tôi muốn có cấu trúc module/gói như sau:python module ước thứ bậc tên

/__init__.py 
/mymodule.py 
/mymodule/ 
/mymodule/__init__.py 
/mymodule/submodule.py 

Và sau đó sử dụng các module như:

import mymodule 
import mymodule.submodule 

Nhưng nó có vẻ như tập tin "mymodule. py "xung đột với" mymodule "thư mục.

Quy ước đặt tên chính xác ở đây là gì?

Cảm ơn.

Trả lời

11

Nếu bạn muốn thực hiện một gói, bạn phải hiểu như thế nào Python dịch tên tệp thành tên mô-đun.

Tệp mymodule.py sẽ có sẵn dưới dạng mymodule, giả sử trình thông dịch tìm thấy nó trong một thư mục trong đường dẫn tìm kiếm Python. Nếu bạn đang sử dụng hệ thống tệp phân biệt chữ hoa chữ thường, nó cũng có thể được nhập bằng cách viết hoa khác (nhưng bạn nên tránh sử dụng hành vi phụ thuộc vào hệ thống).

Gói là thư mục có tệp __init__.py trong đó. Đã có một số chuyển động gần đây cho phép các gói không có các tệp đó, nhưng tôi sẽ bỏ qua trường hợp ít phổ biến hơn cho câu trả lời này. Một gói sẽ trở thành một mô-đun bên trong Python, với mã của nó đến từ tệp __init__.py. Vì vậy, các tập tin mypackage/__init__.py có thể được nhập khẩu là mypackage.

Không có ý nghĩa đối với tệp __init__.py trực tiếp trong đường dẫn tìm kiếm Python (tốt, tôi cho rằng bạn có thể nhập nó là mô-đun __init__, nhưng điều này có thể là một ý tưởng tồi).

Vì vậy, đối với tình hình của bạn, đây là cách bố trí hệ thống tập tin thích hợp:

toplevel/ 
    mymodule/ 
     __init__.py  # put code here for mymodule 
     submodule.py # put code here for mymodule.submodule 

Chỉ có thư mục toplevel phải ở trong đường dẫn tìm kiếm Python.

+0

Tôi đã thấy không gian dân gian của Python đặt mã quan trọng trong 'mymodule/__ init __. Py', ví dụ: [Alex Martelli] (http://stackoverflow.com/a/2361278/188535), mà dường như là mâu thuẫn với điều này. (Không phải là tôi nhất thiết phải đồng ý với điều đó ...) – detly

+2

Đó là sự thật. Một kiểu phổ biến hơn là đặt mã thực tế cho 'mymodule' vào một mô-đun con không có giấy tờ, sau đó nhập API công khai cho nó vào' __init __. Py'. – Blckknght

+0

cảm ơn câu trả lời thông tin. Thật đáng tiếc là python cần những hacks bẩn như vậy để làm một điều hiển nhiên. –

4

Bạn đang xử lý một package. Cấu trúc gói bạn cần có là:

/some-parent-directory # This needs to be on sys.path 
    /mymodule # This is not really a module - it's a package 
     __init__.py # import mymodule 
     # init is loaded when you `import mymodule` or anything below it 
     some.py # import mymodule.some 
     implementation.py # import mymodule.implementation 
     files.py # import mymodule.files 
     /submodule 
      __init__.py # import mymodule.submodule 
      # init is loaded when you `import mymodule.submodule` or anything below it 
      submodule_impl.py # import mymodule.submodule.submodule_impl 
      goes.py # import mymodule.submodule.goes 
      here.py # import mymodule.submodule.here 

Chừng nào các mẹ thư mục là trên sys.path bạn sẽ có thể gọi import mymodule hoặc from mymodule.submodule import something mà không vấn đề.

Nếu bạn muốn một cái gì đó có sẵn từ cấp độ gốc của gói (ví dụ: from mymodule import SomeItem hoặc từ một gói phụ from mymodule.submodule import AnotherItem) thì bạn có thể nhập nó vào tệp __init__.py thích hợp. Ví dụ:

Ví dụ: giả sử bạn muốn lớp CustomClass được xác định trong mô-đun submodule_impl.py để có thể nhập trực tiếp từ submodule. submodule/__init__.py của bạn sẽ phải chứa sau:

from .submodule_impl import CustomClass 

Sau đó, bạn sẽ có thể nhập CustomClass trực tiếp từ submodule (tức from mymodule.submodule import CustomClass)