Có một loạt các câu hỏi nhập python
nhập vòng này trên web. Tôi đã chọn đóng góp cho chủ đề này vì truy vấn có nhận xét của Ray Hettinger hợp pháp hoá trường hợp sử dụng của một lần nhập tròn, nhưng đề xuất một giải pháp mà tôi tin là không thực sự tốt - chuyển nhập vào phương thức.
Ngoài quyền hettinger, ba kỹ khuyến cáo để phản đối phổ biến là cần thiết:
- Tôi chưa bao giờ được lập trình trong Java. Tôi không cố gắng làm phong cách Java.
- Tái cấu trúc không phải lúc nào cũng hữu ích hoặc hiệu quả.API logic đôi khi ra lệnh cấu trúc làm cho các tham chiếu nhập đệ quy không thể tránh khỏi. Hãy nhớ rằng, mã tồn tại cho người dùng, không phải là người lập trình.
- Kết hợp các mô-đun khá lớn có thể gây ra các vấn đề về khả năng đọc và bảo trì có thể tồi tệ hơn nhiều so với một hoặc hai lần nhập khẩu đệ quy.
Bên cạnh đó, tôi tin rằng khả năng bảo trì và khả năng đọc dictates rằng hàng nhập khẩu được nhóm lại ở phía trên cùng của tập tin, xảy ra một lần duy nhất cho mỗi tên cần thiết, và rằng from module import name
phong cách là một lợi thế (ngoại trừ có lẽ cho tên mô-đun rất ngắn với nhiều chức năng, ví dụ: gtk
), vì nó tránh lặp lại sự lộn xộn bằng lời nói và làm cho phụ thuộc rõ ràng.
Bằng cách đó, tôi sẽ đặt một phiên bản đơn giản của trường hợp sử dụng của riêng tôi đã mang tôi đến đây và cung cấp giải pháp của tôi.
Tôi có hai mô-đun, mỗi mô-đun xác định nhiều lớp. surface
xác định các bề mặt hình học như mặt phẳng, hình cầu, hyperboloids, v.v. path
xác định các hình dạng phẳng như đường thẳng, vòng tròn hyperbolae, ... Về mặt logic, đây là những loại riêng biệt và tái cấu trúc không phải là một lựa chọn từ quan điểm của các yêu cầu API. Tuy nhiên, hai loại này là thân mật.
Một hoạt động hữu ích là giao nhau hai bề mặt, ví dụ, giao điểm của hai mặt phẳng là một đường hoặc giao điểm của mặt phẳng và hình cầu là hình tròn.
Nếu ví dụ, trong surface.py
bạn làm việc nhập khẩu thẳng về phía trước cần thiết để thực hiện các giá trị trả về cho một hoạt động giao lộ:
from path import Line
bạn nhận được:
Traceback (most recent call last):
File "surface.py", line 62, in <module>
from path import Line
File ".../path.py", line 25, in <module>
from surface import Plane
File ".../surface.py", line 62, in <module>
from path import Line
ImportError: cannot import name Line
hình học, máy bay được sử dụng để xác định các đường dẫn, sau khi tất cả, chúng có thể được định hướng tùy ý trong ba (hoặc nhiều) kích thước. Traceback cho bạn biết cả những gì đang xảy ra và giải pháp.
Chỉ cần thay thế câu lệnh import trong surface.py
với:
try: from path import Line
except ImportError: pass # skip circular import second pass
Các chuỗi các hoạt động trong các dấu vết trở lại vẫn còn xảy ra. Nó chỉ là lần thứ hai thông qua, chúng tôi bỏ qua sự thất bại nhập khẩu. Điều này không quan trọng, vì Line
không được sử dụng ở cấp mô-đun. Do đó, không gian tên cần thiết của surface
được tải vào path
. Do đó, phân tích không gian tên của path
có thể hoàn thành, cho phép nó được nạp vào surface
, hoàn thành cuộc gặp gỡ đầu tiên với from path import Line
. Do đó việc phân tích cú pháp không gian tên của surface
có thể tiến hành và hoàn thành, tiếp tục với bất kỳ điều gì khác có thể cần thiết.
Đây là một thành ngữ dễ và rất rõ ràng. Cú pháp try: ... except ...
rõ ràng và ngắn gọn ghi lại vấn đề nhập khẩu vòng tròn, giảm bớt bất kỳ bảo trì nào trong tương lai có thể được yêu cầu. Sử dụng nó bất cứ khi nào một refactor thực sự là một ý tưởng tồi.
Không cần phải loại bỏ việc nhập vòng tròn cho thiết kế tốt. Việc chuyển nhập vào định nghĩa phương thức là một cách hợp lý để trì hoãn việc nhập. –