2011-03-10 29 views
33

Tôi đã tạo một mô-đun có tên util cung cấp các lớp và chức năng tôi thường sử dụng trong Python. Một số người trong số họ cần các tính năng được nhập. Những ưu và khuyết điểm của việc nhập khẩu những thứ cần thiết bên trong định nghĩa lớp/chức năng là gì? Có tốt hơn import ở đầu tệp mô-đun không? Nó là một ý tưởng tốt?Nhập khẩu bên trong lớp/chức năng định nghĩa - nó là một ý tưởng tốt?

+1

thể trùng lặp của [Tốt hay xấu thực hành bằng Python: nhập khẩu ở giữa của một tập tin] (http://stackoverflow.com/questions/1188640/good-or-bad-practice-in- python-import-in-the-middle-of-a-file) –

Trả lời

37

Đó là phong cách phổ biến nhất để đưa mỗi nhập ở phía trên cùng của tập tin. PEP 8 đề xuất nó, đó là một lý do tốt để làm điều đó để bắt đầu. Nhưng đó không phải là một ý thích, nó có lợi thế (mặc dù không đủ quan trọng để làm cho mọi thứ khác trở thành tội phạm). Nó cho phép tìm kiếm tất cả các nhập khẩu trong nháy mắt, như trái ngược với tìm kiếm thông qua toàn bộ tập tin. Nó cũng đảm bảo mọi thứ được nhập trước khi bất kỳ mã nào khác (có thể phụ thuộc vào một số lần nhập) được thực thi. NameError s thường dễ giải quyết, nhưng chúng có thể gây phiền toái.

Không có ô nhiễm không gian tên (đáng kể) cần tránh bằng cách giữ mô-đun ở phạm vi nhỏ hơn, vì tất cả những gì bạn thêm là mô-đun thực tế (no, import * doesn't count and probably shouldn't be used anyway). Các chức năng bên trong, bạn sẽ nhập lại trên mọi cuộc gọi (không thực sự có hại vì mọi thứ được nhập một lần, nhưng không được cho phép).

+0

Tôi đã thay đổi lựa chọn của mình thành câu trả lời này. Tôi phân tích nó và nó là tốt nhất cho đến nay. –

+0

Tôi nghĩ rằng đối số tốt nhất cho điều này là: Nếu bạn nhập tệp, bạn muốn kiểm tra khi nhập nếu bạn có tất cả các gói phù hợp, không phải tại thời điểm bạn sẽ sử dụng một hàm nhất định. Tất nhiên nó có thể là bạn không cần tất cả các gói (tôi đoán đây là nhược điểm) –

2

Tôi tin rằng đó là thực hành tốt nhất (theo một số PEP) mà bạn giữ các câu lệnh nhập vào đầu mô-đun. Bạn có thể thêm câu lệnh nhập vào tệp __init__.py, sẽ nhập các mô-đun đó vào tất cả các mô-đun bên trong gói.

Vì vậy, ... đó chắc chắn là điều bạn có thể làm theo cách bạn đang làm, nhưng nó không được khuyến khích và thực sự không cần thiết.

12

PEP8, hướng dẫn phong cách Python, nói rằng:

Nhập khẩu luôn đặt ở phía trên cùng của tập tin, ngay sau khi bất kỳ mô-đun ý kiến ​​và docstrings, và trước khi globals mô-đun và hằng số.

Tất nhiên đây không phải là quy tắc cứng và nhanh và việc nhập có thể đi bất cứ nơi nào bạn muốn. Nhưng đặt chúng ở đầu là cách tốt nhất để đi về nó. Bạn có thể nhập tất nhiên trong các hàm hoặc một lớp.

Nhưng lưu ý bạn không thể làm điều này:

def foo(): 
    from os import * 

Bởi vì:

SyntaxWarning: import * only allowed at module level 
+0

Khi tôi đưa các câu lệnh nhập vào phần đầu của mô đun, và sau đó sử dụng mô đun này trong một tệp khác và gọi 'dir (util)' trong nó, tôi không chỉ thấy tên của các hàm/lớp mà tôi đã định nghĩa bên trong 'util.py' mà còn là' import' được tạo ở đó. Liệu nó có tốt không? –

+0

Có, vì 'import' thực hiện tất cả các câu lệnh trong tệp nguồn được tải. Vì vậy, giả sử có một mô-đun 'X' nhập' Y'. Bây giờ khi chúng ta nhập 'X' vào một mô-đun khác,' Y' cũng được nhập. – user225312

+0

Tôi chỉ nghĩ rằng nó vi phạm đóng gói như bất cứ ai có một số truy cập vào việc thực hiện (được thông tin về các mô-đun tôi đã sử dụng). –

2

Trong khi các câu trả lời khác chủ yếu là đúng, có một lý do tại sao python cho phép điều này.

Không thông minh khi nhập các nội dung thừa không cần thiết. Vì vậy, nếu bạn muốn, ví dụ: phân tích cú pháp XML thành một cây phần tử, nhưng không muốn sử dụng trình phân tích cú pháp XML dựng sẵn chậm nếu lxml có sẵn, bạn sẽ cần phải kiểm tra điều này tại thời điểm bạn cần gọi trình phân tích cú pháp.

Và thay vì ghi nhớ sự sẵn có của lxml ngay từ đầu, tôi sẽ thích try nhập khẩu và sử dụng lxml, except nó không có ở đó, trong trường hợp này tôi muốn dự phòng cho xml mô-đun được xây dựng trong.

1

Giống như câu trả lời của cừu bay, tôi đồng ý rằng những người khác là đúng, nhưng tôi đặt hàng nhập khẩu ở những nơi khác như trong __init__() thường trình và các cuộc gọi chức năng khi tôi đang phát triển mã. Sau khi lớp học hoặc chức năng của tôi đã được kiểm tra và chứng minh để làm việc với việc nhập khẩu bên trong nó, tôi thường cho nó một mô-đun riêng của nó với việc nhập khẩu theo các hướng dẫn PEP8. Tôi làm điều này bởi vì đôi khi tôi quên xóa nhập khẩu sau khi mã refactoring hoặc loại bỏ mã cũ với những ý tưởng xấu. Bằng cách giữ cho hàng nhập khẩu bên trong lớp hoặc chức năng đang được phát triển, tôi chỉ định các phụ thuộc của nó nếu tôi muốn sao chép nó ở nơi khác hoặc quảng bá nó vào mô-đun riêng của mình ...

0

Chỉ chuyển nhập vào phạm vi cục bộ, chẳng hạn như bên trong định nghĩa hàm, nếu cần thiết để giải quyết một vấn đề như tránh nhập vòng tròn hoặc đang cố gắng giảm thời gian khởi tạo của một mô-đun. Kỹ thuật này đặc biệt hữu ích nếu nhiều mục nhập không cần thiết tùy thuộc vào cách chương trình thực thi. Bạn cũng có thể muốn chuyển nhập vào một hàm nếu các mô-đun chỉ được sử dụng trong hàm đó. Lưu ý rằng tải một mô-đun lần đầu tiên có thể tốn kém do khởi tạo một lần của mô-đun, nhưng tải một mô-đun nhiều lần là hầu như miễn phí, chỉ tốn một vài tra cứu từ điển. Ngay cả khi tên mô-đun đã hết phạm vi, mô-đun có thể có sẵn trong sys.modules.

https://docs.python.org/3/faq/programming.html#what-are-the-best-practices-for-using-import-in-a-module

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