Mengimpor modul Python pada saat digunakan

8

Seringkali di perpustakaan Python pribadi saya, saya melakukan sesuatu seperti ini:

class MyClass:

    # ...

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

Alasannya adalah bahwa menginisialisasi someGraphicsLibrarymembutuhkan waktu, hingga beberapa detik untuk salah satu perpustakaan yang saya gunakan. Saya tidak selalu perlu memplot hasil saya ketika saya menggunakan kelas ini, jadi masuk akal untuk tidak mengimpornya sampai waktu itu benar-benar digunakan, jika sama sekali.

Ini sepertinya bekerja dengan baik, tapi saya rasa saya belum melihatnya dalam kode orang lain. Jadi pertanyaan saya hanyalah apakah ini dianggap praktik yang baik. Apakah ada jebakan tersembunyi yang diharapkan saat melakukan hal-hal seperti ini?

Nathaniel
sumber
1
Ini hanyalah bentuk pemuatan malas , yang tidak terlalu istimewa.
Doc Brown
1
Selain dari mungkin menjadi sedikit jelek, tidak ada alasan nyata mengapa Anda tidak bisa melakukan ini. Dan jika impor perpustakaan membutuhkan banyak waktu, bahkan ada alasan yang sah untuk melakukannya. Saya hanya akan membuat titik untuk melakukan ini jarang. Sebagian besar impor seharusnya tidak selambat ini.
Neil
@DocBrown Saya tidak mengatakan itu istimewa, hanya bertanya apakah itu dianggap praktik yang baik / buruk di Python secara khusus.
Nathaniel
@Nathaniel: tampaknya ada kepercayaan takhayul akan keberadaan "praktik terbaik" absolut di antara banyak pengembang - yang merupakan omong kosong IMHO, "praktik" apa pun memiliki pro dan kontra, dan apa yang baik atau buruk hanya dapat dievaluasi secara spesifik konteks. Contoh Anda di atas terlihat masuk akal bagi saya, itu sederhana dan jelas, dan satu-satunya kelemahan nyata adalah, semakin sulit untuk melihat semua dependensi modul secara sekilas (yang merupakan poin # 3 dalam jawaban Kevin). Jadi, jika Anda berpikir peningkatan kinerja sepadan dengan kerumitan, maka praktik ini baik, jika tidak, praktik ini buruk.
Doc Brown

Jawaban:

9

Ini biasanya bukan praktik yang baik, karena beberapa alasan:

  1. Sebagian besar waktu, metode ini akan cepat, tetapi saat pertama kali Anda menyebutnya, itu akan lambat. Itu jauh lebih mudah diprediksi daripada impor waktu startup.
  2. Jika impor gagal karena sejumlah alasan, Anda tidak akan mengetahuinya sampai Anda memanggil metode pada saat runtime.
  3. Lebih sulit untuk melihat modul mana yang menjadi sandaran modul Anda, karena tidak terdaftar di bagian atas file.
  4. Jika modul benar-benar membutuhkan "beberapa detik" untuk diimpor, itu mungkin melakukan terlalu banyak dalam logika waktu impornya. Logika waktu-impor umumnya harus melakukan "cukup" untuk membuat modul dapat digunakan, dan tidak boleh membuat objek global yang berat. Kadang-kadang benda seperti itu diperlukan, tetapi harus hati-hati diteliti.

Namun, terkadang ini adalah Ide yang Baik, misalnya:

  1. Saat mengimplementasikan array-like , Anda mungkin perlu menggunakan metode numpyAnda __array__(). Tetapi Anda mungkin tidak ingin bergantung pada numpyfungsionalitas lain dari modul Anda, jadi lebih baik mengimpor numpysaja __array__()untuk menghindari mengambil ketergantungan tambahan saat itu tidak diperlukan. Ini tidak mengalami masalah 1 dan 2 karena numpysudah pernah diimpor satu kali sebelumnya (ini adalah hal yang memanggil __array__()sejak awal!), Dan itu tidak menderita masalah 3 karena numpybukan dependensi "nyata" dari modul Anda.
  2. Sebelum PEP 553 , breakpoint tradisional tampak seperti ini: import pdb; pdb.set_trace(). Anda tidak ingin meletakkan import pdbdi bagian atas modul karena breakpoint adalah baris sementara kode yang akan dihapus, dan memindahkan impor jauh akan membuat hal itu sulit. Ini sudah usang ketika builtin breakpoint()ditambahkan, jadi sekarang Anda tidak perlu impor inline.
Kevin
sumber
4
Anda lupa menyebutkan bahwa contoh yang diposting oleh OP mirip dengan contoh "Ide bagus # 1" dalam jawaban Anda. Itu terlihat seperti kelas atau modul yang memiliki fungsionalitas inti yang independen dari merencanakan dan dapat digunakan tanpa lib grafik.
Doc Brown
@DocBrown: MyClassbukan kata benda yang berarti, jadi saya pikir Anda melompat ke kesimpulan.
Kevin
Yah, saya meluangkan waktu untuk membaca posting secara penuh. Mungkin saya melakukan beberapa tebakan, tetapi mari kita lihat apa yang dipikirkan OP tentang hal itu (dan jangan salah, jawaban Anda sudah mendapat dukungan dari saya).
Doc Brown
Komentar pertama @Kevin Doc Brown adalah interpretasi yang benar dari posting saya. (+1, ini adalah jawaban yang membantu.)
Nathaniel