Python lười nhập khẩu

Sự phụ thuộc vòng tròn xảy ra khi hai hoặc nhiều mô-đun phụ thuộc vào nhau. Điều này là do thực tế là mỗi mô-đun được xác định theo mô-đun khác [Xem Hình 1]

Ví dụ

functionA[]:
    functionB[]

functionB[]:
    functionA[]

Đoạn mã trên mô tả một sự phụ thuộc vòng tròn khá rõ ràng. functionA[] gọi

functionB[]:
    functionA[]
0, do đó tùy thuộc vào nó và
functionB[]:
    functionA[]
0 gọi functionA[]. Loại phụ thuộc vòng tròn này có một số vấn đề rõ ràng, chúng tôi sẽ mô tả thêm một chút trong phần tiếp theo

Hình 1

Các vấn đề với phụ thuộc vòng tròn

Phụ thuộc tròn có thể gây ra một số vấn đề trong mã của bạn. Ví dụ: nó có thể tạo ra sự liên kết chặt chẽ giữa các mô-đun và do đó, giảm khả năng sử dụng lại mã. Thực tế này cũng làm cho mã khó bảo trì hơn trong thời gian dài.

Ngoài ra, các phụ thuộc vòng tròn có thể là nguồn gốc của các lỗi tiềm ẩn, chẳng hạn như đệ quy vô hạn, rò rỉ bộ nhớ và hiệu ứng xếp tầng. Nếu bạn không cẩn thận và bạn có sự phụ thuộc vòng tròn trong mã của mình, thì có thể rất khó để gỡ lỗi nhiều vấn đề tiềm ẩn mà nó gây ra

Nhập khẩu tuần hoàn là gì?

Nhập vòng là một dạng phụ thuộc vòng được tạo bằng câu lệnh nhập trong Python

Ví dụ: hãy phân tích đoạn mã sau

Khi Python nhập một mô-đun, nó sẽ kiểm tra sổ đăng ký mô-đun để xem mô-đun đó đã được nhập chưa. Nếu mô-đun đã được đăng ký, Python sẽ sử dụng đối tượng hiện có đó từ bộ đệm. Sổ đăng ký mô-đun là một bảng các mô-đun đã được khởi tạo và lập chỉ mục theo tên mô-đun. Bảng này có thể được truy cập thông qua

functionB[]:
    functionA[]
3

Nếu nó chưa được đăng ký, Python sẽ tìm mô-đun, khởi tạo nó nếu cần và thực thi nó trong không gian tên của mô-đun mới

Trong ví dụ của chúng tôi, khi Python đạt đến

functionB[]:
    functionA[]
4, nó sẽ tải và thực thi nó. Tuy nhiên, module2 cũng gọi module1, từ đó xác định
functionB[]:
    functionA[]
5

Sự cố xảy ra khi ________ 10 cố gọi mô-đun 1 của ________ 11. Vì mô-đun 1 đã được tải trước và đến lượt mô-đun 2 được tải trước khi nó có thể đạt đến

functionB[]:
    functionA[]
1, hàm đó chưa được xác định và đưa ra lỗi khi được gọi

$ python __init__.py
Hello, World!
Traceback [most recent call last]:
  File "__init__.py", line 3, in 
    module1.function1[]
  File "/Users/scott/projects/sandbox/python/circular-dep-test/module1/__init__.py", line 5, in function1
    module2.function2[]
  File "/Users/scott/projects/sandbox/python/circular-dep-test/module2/__init__.py", line 6, in function2
    module1.function3[]
AttributeError: 'module' object has no attribute 'function3'

Cách khắc phục phụ thuộc vòng tròn

Nói chung, nhập khẩu vòng tròn là kết quả của thiết kế xấu. Một phân tích sâu hơn về chương trình có thể đã kết luận rằng phần phụ thuộc không thực sự cần thiết hoặc chức năng phụ thuộc có thể được chuyển sang các mô-đun khác không chứa tham chiếu vòng

Một giải pháp đơn giản là đôi khi cả hai mô-đun chỉ có thể được hợp nhất thành một mô-đun lớn hơn. Mã kết quả từ ví dụ của chúng tôi ở trên sẽ giống như thế này

Tuy nhiên, mô-đun được hợp nhất có thể có một số chức năng không liên quan [khớp nối chặt chẽ] và có thể trở nên rất lớn nếu hai mô-đun đã có nhiều mã trong đó

Vì vậy, nếu điều đó không hiệu quả, một giải pháp khác có thể là trì hoãn việc nhập module2 để chỉ nhập khi cần. Điều này có thể được thực hiện bằng cách đặt nhập module2 trong định nghĩa của

functionB[]:
    functionA[]
5

Hãy xem hướng dẫn thực hành, thực tế của chúng tôi để học Git, với các phương pháp hay nhất, tiêu chuẩn được ngành chấp nhận và bao gồm bảng gian lận. Dừng các lệnh Git trên Google và thực sự tìm hiểu nó

Trong trường hợp này, Python sẽ có thể tải tất cả các chức năng trong mô-đun 1 và sau đó chỉ tải mô-đun 2 khi cần

Cách tiếp cận này không mâu thuẫn với cú pháp Python, như tài liệu Python nói. "Thông thường nhưng không bắt buộc phải đặt tất cả các câu lệnh nhập ở đầu mô-đun [hoặc tập lệnh, đối với vấn đề đó]"

Tài liệu Python cũng nói rằng nên sử dụng

functionB[]:
    functionA[]
4, thay vì các câu lệnh khác, chẳng hạn như
functionB[]:
    functionA[]
5 hoặc
functionB[]:
    functionA[]
6

Bạn cũng có thể thấy nhiều cơ sở mã sử dụng nhập bị trì hoãn ngay cả khi không có phụ thuộc vòng tròn, giúp tăng tốc thời gian khởi động, vì vậy đây hoàn toàn không được coi là phương pháp tồi [mặc dù nó có thể là thiết kế tồi, tùy thuộc vào dự án của bạn]

kết thúc

Nhập khẩu vòng tròn là một trường hợp cụ thể của tham chiếu vòng tròn. Nói chung, chúng có thể được giải quyết bằng thiết kế mã tốt hơn. Tuy nhiên, đôi khi, thiết kế kết quả có thể chứa một lượng lớn mã hoặc trộn lẫn các chức năng không liên quan [liên kết chặt chẽ]

Bạn đã chạy nhập vòng tròn trong mã của riêng mình chưa?

Chủ Đề