PEP 8 mengatakan:
- Impor selalu diletakkan di bagian atas file, tepat setelah komentar modul dan docstrings, dan sebelum global modul dan konstanta.
Kadang-kadang, saya melanggar PEP 8. Beberapa kali saya mengimpor barang di dalam fungsi. Sebagai aturan umum, saya melakukan ini jika ada impor yang hanya digunakan dalam satu fungsi.
Ada opini?
EDIT (alasan saya merasa mengimpor fungsi bisa menjadi ide yang bagus):
Alasan utama: Ini dapat membuat kode lebih jelas.
- Saat melihat kode fungsi, saya mungkin bertanya pada diri sendiri: "Apa itu fungsi / kelas xxx?" (xxx digunakan di dalam fungsi). Jika saya memiliki semua impor saya di bagian atas modul, saya harus melihat ke sana untuk menentukan apa itu xxx. Ini lebih merupakan masalah saat menggunakan
from m import xxx
. Melihatm.xxx
fungsinya mungkin memberi tahu saya lebih banyak. Tergantung pada apam
itu: Apakah itu modul / package (import m
) tingkat atas yang terkenal ? Atau apakah itu sub-modul / paket (from a.b.c import m
)? - Dalam beberapa kasus, memiliki informasi tambahan ("Apa itu xxx?") Yang dekat dengan tempat xxx digunakan dapat membuat fungsi lebih mudah dipahami.
python
conventions
codeape
sumber
sumber
Jawaban:
Dalam jangka panjang, saya pikir Anda akan menghargai memiliki sebagian besar impor Anda di bagian atas file, dengan cara itu Anda dapat mengetahui sekilas betapa rumitnya modul Anda dengan apa yang perlu diimpor.
Jika saya menambahkan kode baru ke file yang sudah ada, saya biasanya akan melakukan impor di tempat yang diperlukan dan kemudian jika kode tetap ada, saya akan membuatnya lebih permanen dengan memindahkan baris impor ke bagian atas file.
Satu hal lagi, saya lebih suka mendapatkan
ImportError
pengecualian sebelum kode apa pun dijalankan - sebagai pemeriksaan kewarasan, jadi itulah alasan lain untuk mengimpor di bagian atas.Saya gunakan
pyChecker
untuk memeriksa modul yang tidak digunakan.sumber
Ada dua kesempatan di mana saya melanggar PEP 8 dalam hal ini:
import pdb; pdb.set_trace()
Ini berguna b / c Saya tidak ingin meletakkanimport pdb
di bagian atas setiap modul yang mungkin ingin saya debug, dan mudah diingat untuk menghapus impor ketika saya menghapus breakpoint.Di luar dua kasus ini, ada baiknya untuk menempatkan semuanya di atas. Itu membuat dependensi lebih jelas.
sumber
Berikut adalah empat kasus penggunaan impor yang kami gunakan
import
(danfrom x import y
danimport x as y
) di atasPilihan untuk Impor. Di atas.
Impor Bersyarat. Digunakan dengan JSON, pustaka XML dan sejenisnya. Di atas.
Impor Dinamis. Sejauh ini, kami hanya memiliki satu contoh tentang ini.
Perhatikan bahwa impor dinamis ini tidak membawa kode, tetapi membawa struktur data kompleks yang ditulis dengan Python. Ini seperti potongan data yang diawetkan kecuali kita membuat acar dengan tangan.
Ini juga, kurang lebih, di bagian atas modul
Inilah yang kami lakukan untuk membuat kode lebih jelas:
Buat modul tetap pendek.
Jika saya memiliki semua impor saya di bagian atas modul, saya harus melihat ke sana untuk menentukan apa itu nama. Jika modulnya pendek, itu mudah dilakukan.
Dalam beberapa kasus, memiliki informasi tambahan yang dekat dengan tempat nama digunakan dapat membuat fungsi lebih mudah dipahami. Jika modulnya pendek, itu mudah dilakukan.
sumber
Satu hal yang perlu diingat: impor yang tidak perlu dapat menyebabkan masalah kinerja. Jadi jika ini adalah fungsi yang akan sering dipanggil, lebih baik Anda meletakkan impor di atas. Tentu saja ini adalah pengoptimalan, jadi jika ada kasus yang valid untuk dibuat bahwa mengimpor di dalam fungsi lebih jelas daripada mengimpor di bagian atas file, yang mengalahkan kinerja dalam banyak kasus.
Jika Anda melakukan IronPython, saya diberitahu bahwa lebih baik mengimpor fungsi di dalam (karena mengkompilasi kode di IronPython bisa lambat). Dengan demikian, Anda mungkin bisa mendapatkan cara dengan mengimpor fungsi di dalam. Tapi selain itu, saya berpendapat bahwa melawan konvensi itu tidak layak.
Hal lain yang ingin saya sampaikan adalah bahwa ini mungkin masalah pemeliharaan potensial. Apa yang terjadi jika Anda menambahkan fungsi yang menggunakan modul yang sebelumnya hanya digunakan oleh satu fungsi? Apakah Anda akan ingat untuk menambahkan impor ke bagian atas file? Atau apakah Anda akan memindai setiap fungsi untuk impor?
FWIW, ada kasus di mana masuk akal untuk mengimpor di dalam fungsi. Misalnya, jika Anda ingin menyetel bahasa di cx_Oracle, Anda perlu menyetel
_
variabel lingkungan NLS LANG sebelum diimpor. Jadi, Anda mungkin melihat kode seperti ini:sumber
Saya telah melanggar aturan ini sebelumnya untuk modul yang menguji sendiri. Artinya, mereka biasanya hanya digunakan untuk dukungan, tetapi saya menetapkan yang utama untuk mereka sehingga jika Anda menjalankannya sendiri, Anda dapat menguji fungsionalitasnya. Dalam hal ini saya terkadang mengimpor
getopt
dancmd
hanya di main, karena saya ingin menjelaskan kepada seseorang yang membaca kode bahwa modul ini tidak ada hubungannya dengan operasi normal modul dan hanya disertakan untuk pengujian.sumber
Berasal dari pertanyaan tentang memuat modul dua kali - Mengapa tidak keduanya?
Impor di bagian atas skrip akan menunjukkan ketergantungan dan impor lain dalam fungsi dengan membuat fungsi ini lebih atomic, sementara tampaknya tidak menyebabkan kerugian kinerja, karena impor berurutan itu murah.
sumber
Selama
import
dan tidakfrom x import *
, Anda harus meletakkannya di atas. Ia hanya menambahkan satu nama ke namespace global, dan Anda tetap menggunakan PEP 8. Selain itu, jika nanti Anda membutuhkannya di tempat lain, Anda tidak perlu memindahkan apa pun.Ini bukan masalah besar, tetapi karena hampir tidak ada perbedaan, saya sarankan untuk melakukan apa yang dikatakan PEP 8.
sumber
from x import *
dalam fungsi akan menghasilkan SyntaxWarning, setidaknya di 2.5.Lihatlah pendekatan alternatif yang digunakan dalam sqlalchemy: injeksi ketergantungan:
Perhatikan bagaimana perpustakaan yang diimpor dideklarasikan di dekorator, dan diteruskan sebagai argumen ke fungsi !
Pendekatan ini membuat kode lebih bersih, dan juga bekerja 4,5 kali lebih cepat daripada sebuah
import
pernyataan!Tolok ukur: https://gist.github.com/kolypto/589e84fbcfb6312532658df2fabdb796
sumber
Dalam modul yang merupakan modul 'normal' dan dapat dijalankan (yaitu memiliki
if __name__ == '__main__':
-section), saya biasanya mengimpor modul yang hanya digunakan saat menjalankan modul di dalam bagian utama.Contoh:
sumber
Ada kasus lain (mungkin "sudut") di mana mungkin bermanfaat
import
di dalam fungsi yang jarang digunakan: mempersingkat waktu startup.Saya menabrak tembok itu sekali dengan program yang agak kompleks yang berjalan di server IoT kecil yang menerima perintah dari jalur serial dan melakukan operasi, mungkin operasi yang sangat kompleks.
Menempatkan
import
pernyataan di atas file berarti semua impor diproses sebelum server dimulai; sejakimport
daftar termasukjinja2
,lxml
,signxml
dan "berat bobot" lainnya (dan SoC tidak sangat kuat) ini berarti menit sebelum instruksi pertama benar-benar dieksekusi.OTOH menempatkan sebagian besar impor dalam fungsi Saya dapat membuat server "hidup" pada baris serial dalam hitungan detik. Tentu saja ketika modul benar-benar dibutuhkan saya harus membayar harganya (Catatan: ini juga dapat dikurangi dengan menelurkan tugas latar belakang yang dilakukan
import
dalam waktu idle).sumber