2009-12-16 47 views
12

Tôi có hai câu hỏi 'nhập' Python liên quan. Họ có thể dễ dàng kiểm tra, nhưng tôi muốn câu trả lời được xác định bằng ngôn ngữ và không cụ thể cho việc triển khai và tôi cũng quan tâm đến phong cách/quy ước, vì vậy tôi yêu cầu ở đây thay thế.Cơ chế nhập khẩu bằng Python

1)

Nếu module A nhập khẩu mô-đun B, và mô-đun B nhập khẩu mô-đun C, có thể mã trong module A tham khảo mô-đun C không có nhập khẩu rõ ràng? Nếu vậy, tôi có đúng trong giả định đây là thực hành không tốt?

2)

Nếu tôi nhập mô-đun A.B.C, có nhập mô-đun A và A.B không? Nếu vậy, có phải là theo quy ước tốt hơn để rõ ràng import A; import A.B; import A.B.C?

+0

"ngôn ngữ được xác định và không thực hiện cụ thể" Bạn có nói rằng việc triển khai Python bằng cách nào đó khác nhau không? Bạn nhận thức được sự khác biệt cụ thể nào? AFAIK không có. –

+0

Có lẽ không có bất kỳ sự khác biệt, nhưng bất cứ điều gì không được xác định bởi spec là lên đến việc thực hiện. Các tài liệu Python được rải rác với các thông tin chi tiết về việc triển khai CPython có thể không áp dụng trong các triển khai khác. –

Trả lời

12

Điều đầu tiên bạn cần biết là ngôn ngữ Python KHÔNG phải là tiêu chuẩn ISO. Điều này khá khác với C/C++, và nó có nghĩa là không có cách "thích hợp" để xác định hành vi ngôn ngữ - CPython có thể làm điều gì đó chỉ vì nó được mã hóa theo cách đó, và Jython có thể làm theo cách khác.

về câu hỏi của bạn, hãy nhớ rằng "nhập" mô-đun là thao tác gồm hai phần: trước tiên mô-đun được tải - nếu chưa bao giờ có, ví dụ: nếu nó không có sẵn trong sys.modules, thì tên được gắn với module đó trong không gian tên cục bộ.

do đó:

1) Có, bạn có thể tham khảo bất cứ điều gì bạn muốn từ mô-đun bằng cách cung cấp một không gian tên thích hợp, ví dụ bạn sẽ phải làm một cái gì đó giống như

BCname = "cái gì đó"

Và tôi nghĩ rằng đây là rất hiếm khi được thực hiện trong các chương trình Python và có thể được coi thực hành xấu vì nó buộc một "bắc cầu dep" - nếu một số việc triển khai mô-đun B được tái cấu trúc và không phụ thuộc vào C nữa, nó sẽ tiếp tục cung cấp mô đun C chỉ để đáp ứng A deps.

Tất nhiên thiết lập __ tất cả __ có thể ngăn chặn điều này và thực hành tốt có thể đặt __ tất cả __ trong tất cả mô-đun của bạn và xuất chỉ các biểu tượng bạn muốn thực sự công khai.

2) Có và không. Làm

import a.b.c.d 

thực hiện đầu tiên giai đoạn nhập khẩu (tải) trên tất cả các mô-đun, nhưng thứ hai chỉ trên (và, đệ quy, trong b đối với c, vv với) nhưng tất cả các module trong chuỗi phải được tham chiếu bởi không gian tên đầy đủ; sau nhập khẩu như vậy, bạn có thể làm

a.something 
a.b.something 
a.b.c.something 

nhưng bạn không thể làm

c.something 
b.something 

Tôi phải thừa nhận rằng loại sử dụng là khá hiếm cũng; Tôi thường thích "từ mô-đun nhập khẩu một cái gì đó" cách để nhập khẩu, và nói chung bạn chỉ cần yêu cầu những gì bạn cần - chẳng hạn làm tổ không phổ biến trong các thư viện, cũng không phải việc sử dụng nó là phổ biến.

Nhiều lần có "gói bên ngoài", chỉ được sử dụng cho tổ chức, giữ mô-đun với các lớp học. Rất có thể là a, b, c ở trên chỉ là các gói, và d là một mô-đun thực sự chứa các lớp, các hàm và các đối tượng khác.Vì vậy, cách sử dụng phù hợp sẽ là:

from a.b.c.d import name1, name2, name3 

Tôi hy vọng điều này sẽ làm hài lòng sự tò mò của bạn.

+0

Cảm ơn câu trả lời chi tiết! –

+0

Trong khi không phải ISO, có tham chiếu ngôn ngữ Python xác định hành vi "thích hợp", bao gồm cả nhập khẩu: http://docs.python.org/reference/simple_stmts.html#the-import-statement Tham khảo ngôn ngữ chỉ ra Chi tiết thực hiện CPython, nhưng nhằm mục đích là một đặc tả chung của ngôn ngữ, để nó không phải là tất cả phụ thuộc vào việc triển khai thực hiện. –

11

Alan đưa ra một câu trả lời tuyệt vời, nhưng tôi muốn thêm câu trả lời cho câu hỏi của bạn 1 nó phụ thuộc vào ý nghĩa của bạn bằng cách 'nhập'.

Nếu bạn sử dụng cú pháp from C import x thì x sẽ có sẵn trong không gian tên B. Nếu trong số A, bạn làm import B, bạn sẽ có quyền truy cập vào x từ AB.x.

Nó không phải là quá nhiều thực hành xấu như có khả năng gây nhầm lẫn, và sẽ làm cho gỡ lỗi vv khó khăn hơn như bạn sẽ không nhất thiết phải biết nơi các đối tượng đã đến từ.

+0

Đó là lời giải thích hữu ích, cảm ơn. Tôi đã nghĩ về 'import' giống như nhập gói kiểu Java, nhưng rõ ràng rằng sự giống nhau chỉ đơn thuần là bề ngoài. –

+0

Nếu điều này gây nhầm lẫn, đó không phải là lý do đủ để gọi nó là hành vi xấu? Nó nên được rõ ràng những gì mã không chỉ từ đọc nó IMHO. – jjpe