2012-02-03 35 views
11

thể trùng lặp:
How to properly use relative or absolute imports in Python modules?trăn nhập khẩu tương đối mã ví dụ không hoạt động

Tôi có bố trí tập tin này, như trong ví dụ này: (download tại đây: http://www.mediafire.com/?oug42nzvxrvoms4) http://www.python.org/dev/peps/pep-0328/#guido-s-decision

mô-đunX chứa:

from .moduleY import spam 
from .moduleY import spam as ham 
from . import moduleY 
from ..subpackage1 import moduleY 
from ..subpackage2.moduleZ import eggs 
from ..moduleA import foo 
from ...package import bar 
from ...sys import path 

và đây là những gì sẽ xảy ra:

C:\package\subpackage1>python moduleX.py 
Traceback (most recent call last): 
    File "moduleX.py", line 1, in <module> 
    from .moduleY import spam 
ValueError: Attempted relative import in non-package 

Tôi có python 2.7.2. Tôi có

__init__.py 

tệp trong mọi thư mục. Tại sao mã này không hoạt động?

+4

Tôi thấy câu hỏi này hữu ích hơn so với câu hỏi này đã được đánh dấu là trùng lặp. – ArtOfWarfare

+0

Trình gắn thẻ robot trùng lặp ;-) – nicorellius

Trả lời

20

Từ các tài liệu:

bạn có thể thấy điều này:

nhập khẩu tương đối sử dụng tên thuộc tính của mô-đun để xác định vị trí module trong hệ thống phân cấp gói . Nếu tên của mô-đun không chứa bất kỳ thông tin gói nào (ví dụ: được đặt thành 'chính') thì nhập tương đối được giải quyết như mô-đun là mô-đun cấp cao nhất, bất kể mô-đun nằm ở đâu trên hệ thống tệp.

Bằng cách chạy nó như python moduleX.py, bạn đang thực hiện chính xác ở trên. Thay vào đó, hãy thử điều này:

python -m package.subpackage1.moduleX 

Điều này sẽ nhập mô-đunX và đặt cấp cao nhất vào gói. Chạy từ phía trên cùng của hệ thống phân cấp:

package/ 
    __init__.py 
    subpackage1/ 
     __init__.py 
     moduleX.py 
     moduleY.py 
    subpackage2/ 
     __init__.py 
     moduleZ.py 
    moduleA.py 

tức là trong trường hợp của bạn từ c:\ trực tiếp:

c:\>python -m package.subpackage1.moduleX 

Lưu ý một điều - nhập khẩu trong moduleX.py là những:

from .moduleY import spam 
from .moduleY import spam as ham 
from . import moduleY 
from ..subpackage1 import moduleY 
from ..subpackage2.moduleZ import eggs 
from ..moduleA import foo 
from ...package import bar 
from ...sys import path 

Thứ hai để kéo dài:

from ...package import bar 

yêu cầu thư mục gốc (c:\ trong trường hợp của bạn) là một gói (tức là có __init__.py). Ngoài ra, nó đòi hỏi biến bar được xác định trong package\__init__.py, hiện không có ở đó (vì vậy hãy đặt bar = 'bar!' để kiểm tra).Nó cũng yêu cầu bạn phải lên cấp một - vì vậy bạn phải đặt thư mục package vào một thư mục khác (vì vậy bạn kết thúc với c:\toppackage\package) và chạy c:\python -m toppackage.package.subpackage1.moduleX.

Đối với dòng này:

from ...sys import path 

có một lưu ý ở trên PEP 328 link:

Lưu ý rằng trong khi đó trường hợp cuối cùng là hợp pháp, nó chắc chắn là nản chí ("điên" là từ Guido sử dụng).

Xem thêm SOqs khác về vấn đề này có thể giúp:

Hy vọng điều này sẽ hữu ích.

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