2012-07-30 17 views
17

Hãy tưởng tượng cấu trúc thư mục:Không nên nhập khẩu tuyệt đối theo mặc định trong python27?

 
/
    a/ 
     __init__.py 
     b.py 
     c.py 
    c.py 

file /a/b.py trông giống như:

 
import c 
should_be_absolute = c 

Tất cả các tập tin khác (kể cả __init__) là rỗng.

Khi chạy một kịch bản thử nghiệm (sử dụng python 2.7):

import a.b 
print a.b.should_be_absolute 

với PYTHONPATH=/ từ một thư mục rỗng (do đó không có gì được thêm vào PYTHONPATH từ thư mục hiện hành) tôi nhận được

<module 'a.c' from '/a/c.py'> 

nơi theo đến PEP 328 và tuyên bố import <> is always absolute Tôi mong đợi:

<module 'c' from '/c.py'> 

Kết quả như mong đợi khi tôi xóa tệp /a/c.py.

Tôi đang thiếu gì? Và nếu đây là hành vi đúng - cách nhập mô-đun c từ b (thay vì a.c)?

Cập nhật:

Theo python dev mailing list nó dường như là một lỗi trong tài liệu. Nhập khẩu là không tuyệt đối theo mặc định trong python27.

+0

Con trăn hoàn chỉnh của bạn là gì? Là nó chỉ /? Có thể bạn đang sử dụng tên gói gốc – jdi

+3

FWIW, công cụ này giống như bạn mong đợi ở Python 3. – geoffspear

+0

@jdi - có gốc là điều duy nhất trong PYTHONPATH (đã chỉnh sửa bài đăng gốc để làm rõ hơn) – karolx

Trả lời

26

bạn cần phải thêm from __future__ import absolute_import hoặc sử dụng importlib.import_module('c') trên Python 2,7

Đó là mặc định trên Python 3.

Đã xảy ra lỗi trong Python: __future__.py and its documentation claim absolute imports became mandatory in 2.7, but they didn't.

+2

Bạn đã đúng! Sau khi tìm hiểu thêm, tôi tìm thấy liên kết đến [danh sách gửi thư python-dev] (http://python.6.n6.nabble.com/status-of-absolute-import-w-python-2-7-td1850742.html) xác nhận rằng tính năng absolute_import không được bật theo mặc định trong python27. – karolx

+0

loại vô lý ... –

0

Nếu bạn chỉ thêm / vào PYTHONPATH của mình, khi đó đơn đặt hàng tìm kiếm vẫn có thể tìm kiếm c trong thư mục hiện tại. Sẽ tốt hơn nhiều nếu bạn đặt tất cả mọi thứ dưới một gói rễ, và gọi nó hoàn toàn:

/myPackage 
    a/ 
     __init__.py 
     b.py 
     c.py 
    __init__.py 
    c.py 

Và một PYTHONPATH như: export PYTHONPATH=/:$PYTHONPATH

Vì vậy, trong bạn a.c bạn sẽ làm gì và trong số này:

from myPackage import c 
from myPackage.c import Foo 
import myPackage.c 

Bằng cách này, nó luôn liên quan đến gói của bạn.

+0

Cảm ơn nhưng câu hỏi là nhiều hơn đây là một hành vi đúng hơn là làm thế nào để tổ chức lại mã để làm cho nó hoạt động. Vấn đề thực tế mà tôi đang giải quyết là 'c' là tên của mô-đun xây dựng python và mã trong gói mà tôi đang làm là che nó (và theo tài liệu trăn không nên) – karolx

-1

"Tuyệt đối" không có nghĩa là trang bạn nghĩ; thay vào đó, nó có nghĩa là quy trình giải quyết gói "thông thường" diễn ra: đầu tiên, nó tìm trong thư mục của gói, sau đó trong tất cả các phần tử của sys.path; bao gồm các yếu tố từ PYTHONPATH.

Nếu bạn thực sự muốn, bạn có thể sử dụng các công cụ như mô-đun imp, nhưng tôi khuyên bạn nên sử dụng các công cụ như thế này. Bởi vì nói chung, bạn không bao giờ phải tạo một mô-đun có cùng tên như một trong phân phối Python chuẩn.

+0

Cảm ơn @Ivo nhưng [PEP 328 # lý do-nhập-tuyệt đối-nhập khẩu] (http://www.python.org/dev/peps/pep-0328/#rationale-for-absolute-imports) nói rằng nhập tuyệt đối _sẽ luôn là một mô-đun hoặc gói có thể truy cập từ sys.path_. Không có gì về tra cứu trong thư mục gói đầu tiên. Bạn có thể chỉ ra một số tài liệu ghi lại hành vi mà bạn đã mô tả không? – karolx

+0

http://docs.python.org/reference/simple_stmts.html#import rất rõ ràng về quy trình khi được triển khai: "Nếu mô-đun được nhập được cho là nằm trong gói thì đối số thứ hai được chuyển đến find_module(), __path__ trên gói gốc, được sử dụng làm nguồn của đường dẫn. " – Ivo

+0

"đầu tiên, nó có trong thư mục của gói". Không, đó là nhập tương đối. –

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