Nhập mô-đun Python tại thời điểm sử dụng


8

Thông thường trong các thư viện Python cá nhân của riêng tôi, tôi làm một cái gì đó như thế này:

class MyClass:

    # ...

    def plot(self):
        import someGraphicsLibrary as graphicslib
        graphicslib.plot(self.data)

Lý do là việc khởi tạo someGraphicsLibrarymất một chút thời gian, tối đa vài giây cho một trong những thư viện tôi sử dụng. Tôi không cần phải vẽ sơ đồ kết quả của mình khi tôi sử dụng lớp này, vì vậy sẽ không có ý nghĩa nếu không nhập nó cho đến khi nó thực sự được sử dụng, nếu có.

Điều này có vẻ hoạt động tốt, nhưng tôi không nghĩ rằng tôi đã thấy nó trong mã của bất kỳ ai khác. Vì vậy, câu hỏi của tôi chỉ đơn giản là liệu điều này được coi là một thực hành tốt. Có bất kỳ cạm bẫy tiềm ẩn nào được mong đợi khi làm mọi thứ theo cách này?


1
Đây chỉ đơn giản là một hình thức tải lười biếng , không phải là rất đặc biệt.
Doc Brown

1
Bên cạnh có lẽ là một chút xấu xí, không có lý do thực sự tại sao bạn không thể làm điều này. Và nếu việc nhập thư viện mất quá nhiều thời gian, thậm chí có một lý do chính đáng để làm việc đó. Tôi sẽ chỉ làm cho một điểm để làm điều này hiếm khi. Hầu hết hàng nhập khẩu không nên chậm thế này.
Neil

@DocBrown Tôi không nói nó đặc biệt, chỉ hỏi xem nó có được coi là thực hành tốt / xấu trong Python không.
Nathaniel

@Nathaniel: dường như có một số người tin tưởng mê tín vào sự tồn tại của "thực tiễn tốt nhất" tuyệt đối giữa nhiều nhà phát triển - đó là IMHO vô nghĩa, bất kỳ "thực hành" nào cũng có ưu và nhược điểm, và điều gì tốt hay xấu chỉ có thể được đánh giá cụ thể bối cảnh. Ví dụ của bạn ở trên có vẻ hợp lý với tôi, nó đơn giản và rõ ràng, và nhược điểm thực sự duy nhất là, khó nhìn thấy tất cả các phụ thuộc của một mô-đun trong nháy mắt (đó là điểm số 3 trong câu trả lời của Kevin). Vì vậy, nếu bạn nghĩ rằng cải thiện hiệu suất là giá trị rắc rối, thì thực tế này là tốt, nếu không, thực hành này là xấu.
Doc Brown

Câu trả lời:


9

Đây thường không phải thực hành tốt, vì một số lý do:

  1. Hầu hết thời gian, phương thức sẽ nhanh, nhưng lần đầu tiên bạn gọi nó, nó sẽ chậm. Đó là rất ít dự đoán hơn so với nhập khẩu thời gian khởi động.
  2. Nếu quá trình nhập thất bại vì bất kỳ lý do nào, bạn sẽ không biết điều đó cho đến khi bạn gọi phương thức này trong thời gian chạy.
  3. Thật khó để xem mô-đun nào mà mô-đun của bạn phụ thuộc vào, vì chúng không được liệt kê ở đầu tệp.
  4. Nếu một mô-đun thực sự mất "một vài giây" để nhập, thì nó có thể làm quá nhiều trong logic thời gian nhập của nó. Logic thời gian nhập thường phải làm "vừa đủ" để làm cho mô-đun có thể sử dụng được và không nên đi xung quanh tạo các đối tượng toàn cầu nặng. Đôi khi các đối tượng như vậy là cần thiết, nhưng nó cần được xem xét kỹ lưỡng.

Tuy nhiên, đôi khi đây là một ý tưởng tốt, ví dụ:

  1. Khi thực hiện một mảng giống như , bạn có thể cần phải sử dụng numpytrong __array__()phương thức của mình . Nhưng bạn có thể không muốn phụ thuộc vào numpychức năng khác của mô-đun của mình, vì vậy tốt hơn là chỉ nhập numpybên trong __array__()để tránh phụ thuộc thêm khi không cần thiết. Điều này không gặp phải vấn đề 1 và 2 vì numpyđã được nhập trước đó một lần (đó là điều được gọi __array__()ở vị trí đầu tiên!) Và nó không gặp phải vấn đề 3 vì numpykhông phải là sự phụ thuộc "thực sự" của mô-đun của bạn.
  2. Trước PEP 553 , một điểm dừng truyền thống trông như thế này : import pdb; pdb.set_trace(). Bạn không muốn đặt import pdbở đầu mô-đun vì điểm dừng là một dòng mã tạm thời sẽ bị xóa và việc di chuyển quá xa sẽ khiến việc đó trở nên khó khăn. Điều này đã bị lỗi thời khi nội dung breakpoint()được thêm vào, vì vậy bây giờ bạn không cần nhập nội tuyến.

4
Bạn đã quên đề cập rằng ví dụ được đăng bởi OP trông giống như trường hợp phù hợp với trường hợp "Ý tưởng tốt số 1" trong câu trả lời của bạn. Nó trông giống như một lớp hoặc mô-đun có chức năng cốt lõi độc lập với âm mưu và có thể được sử dụng mà không có lib đồ họa.
Doc Brown

@DocBrown: MyClasskhông phải là một danh từ có ý nghĩa, vì vậy tôi nghĩ rằng bạn đang đi đến kết luận.
Kevin

Vâng, tôi đã dành thời gian để đọc bài viết đầy đủ. Có thể tôi đã đoán được một chút, nhưng hãy xem OP nghĩ gì về nó (và đừng hiểu sai ý tôi, câu trả lời của bạn đã nhận được sự ủng hộ từ tôi).
Doc Brown

Nhận xét đầu tiên của @Kevin Doc Brown là một cách giải thích chính xác cho bài viết của tôi. (+1, đây là một câu trả lời hữu ích.)
Nathaniel
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.