2016-05-10 17 views
49

Tôi đang sử dụng Python 3.5.1. Tôi đọc tài liệu và các gói phần ở đây: https://docs.python.org/3/tutorial/modules.html#packagesCó phải __init__.py không bắt buộc đối với các gói trong Python 3 không?

Bây giờ, tôi có cơ cấu như sau:

/home/wujek/Playground/a/b/module.py 

module.py:

class Foo: 
    def __init__(self): 
     print('initializing Foo') 

Bây giờ, trong khi ở /home/wujek/Playground:

~/Playground $ python3 
>>> import a.b.module 
>>> a.b.module.Foo() 
initializing Foo 
<a.b.module.Foo object at 0x100a8f0b8> 

Tương tự, bây giờ ở nhà, thư mục chính của Playground:

~ $ PYTHONPATH=Playground python3 
>>> import a.b.module 
>>> a.b.module.Foo() 
initializing Foo 
<a.b.module.Foo object at 0x10a5fee10> 

Thực ra, tôi có thể làm tất cả các loại công cụ:

~ $ PYTHONPATH=Playground python3 
>>> import a 
>>> import a.b 
>>> import Playground.a.b 

Tại sao công việc này? Tôi có cần phải có các tệp __init__.py (các tệp trống sẽ hoạt động) trong cả hai ab cho module.py để có thể nhập khi đường dẫn Python trỏ đến thư mục Playground?

này dường như đã thay đổi từ Python 2.7:

~ $ PYTHONPATH=Playground python 
>>> import a 
ImportError: No module named a 
>>> import a.b 
ImportError: No module named a.b 
>>> import a.b.module 
ImportError: No module named a.b.module 

Với __init__.py trong cả ~/Playground/a~/Playground/a/b nó hoạt động tốt.

Trả lời

57

Python 3.3+ có Implicit Namespace Packages cho phép tạo gói mà không cần tệp __init__.py.

Cho phép các gói namespace ngầm có nghĩa là yêu cầu để cung cấp một tập tin __init__.pythể bỏ hoàn toàn, và bị ảnh hưởng ....

Cách cũ với __init__.py file vẫn hoạt động như trong Python 2.

+4

Tôi sẽ đọc các tài liệu, nhưng đó là một chút dài. Có thể tóm tắt nhanh chóng không?Bạn có thể chỉ cho tôi biết: nó vẫn hỗ trợ __init__.py, hoặc hoàn toàn bỏ qua chúng? Nếu nó hỗ trợ họ, sự khác biệt trong chức năng là gì và tại sao tính nhị nguyên này? – wujek

+1

Có, nó vẫn hoạt động. Vì vậy, tất cả các gói Python 2 của bạn với các tập tin '__init __. Py' sẽ làm việc về mặt nhập khẩu (khác biệt khác giữa Python 2 và 3 không được xem xét ở đây). –

+1

Vì vậy, hướng dẫn có lẽ nên được cập nhật. Là một lỗi tài liệu mở ra cho nó? –

2

@ câu trả lời của Mike là đúng nhưng quá thiếu chính xác. Đúng là Python 3.3+ hỗ trợ Gói không gian ngầm tiềm ẩn cho phép tạo gói mà không cần tệp __init__.py.

Tuy nhiên, CHỈ áp dụng cho các tệp EMPTY __init__.py. Vì vậy, EMPTY __init__.py tệp không còn cần thiết và có thể bỏ qua. Nếu bạn muốn nhập mô-đun vào gói, bạn vẫn cần tệp __init__.py liệt kê tất cả các lần nhập.

mục Cấu trúc Ví dụ:

parent_package/ 
    __init__.py   <- EMPTY, NOT NECESSARY in Python 3.3+ 
    child_package/ 
      __init__.py  <- STILL REQUIRED to import all child modules 
      child1.py 
      child2.py 
      child3.py 

__init__ tập tin trong child_package:

import child1 
import child2 
import child3 
Các vấn đề liên quan