Disarankan untuk tidak menggunakan import *
Python.
Adakah yang bisa berbagi alasan untuk itu, sehingga saya bisa menghindarinya nanti?
python
python-import
Antusiasme Perangkat Lunak
sumber
sumber
import *
tidak bekerja untuk saya di tempat pertama dalam Python 2 atau 3.Jawaban:
Karena itu menempatkan banyak barang ke namespace Anda (mungkin membayangi beberapa objek lain dari impor sebelumnya dan Anda tidak akan mengetahuinya).
Karena Anda tidak tahu persis apa yang diimpor dan tidak dapat dengan mudah menemukan dari modul mana barang tertentu diimpor (keterbacaan).
Karena Anda tidak dapat menggunakan alat keren
pyflakes
untuk mendeteksi kesalahan secara statis dalam kode Anda.sumber
numpy.any
membayangiany
ketika mereka melakukannyafrom numpy import *
atau alat "membantu" melakukannya untuk mereka.import *
membuat urutan dariimport
pernyataan yang signifikan ... bahkan untuk modul perpustakaan standar yang biasanya tidak peduli tentang pesanan impor . Sesuatu yang tidak bersalah seperti abjadimport
pernyataan Anda dapat merusak skrip Anda ketika mantan korban perang impor menjadi satu-satunya yang selamat. (Bahkan jika skrip Anda bekerja sekarang dan tidak pernah berubah, itu bisa tiba-tiba gagal beberapa saat kemudian jika modul yang diimpor memperkenalkan nama baru yang menggantikan nama yang Anda andalkan.)Menurut Zen Python :
... tidak bisa berdebat dengan itu, tentunya?
sumber
use strict
(JavaScriptvar
). Sebagai tambahan, tentu saja Python tidak bertulisan (itu sebenarnya sangat diketik). Bagaimanapun, bahkan jika Anda benar, ini masih akan bertentangan dengan Zen Python, dikutip dalam jawaban ini.Anda tidak lolos
**locals()
ke fungsi, bukan?Karena Python tidak memiliki pernyataan "termasuk", dan yang
self
parameter eksplisit, dan scoping aturan yang cukup sederhana, biasanya sangat mudah untuk menunjuk jari pada variabel dan memberitahu mana yang objek berasal dari - tanpa membaca modul lain dan tanpa jenis IDE (yang terbatas di jalan introspeksi, oleh karena bahasanya sangat dinamis).The
import *
istirahat semua itu.Juga, ia memiliki kemungkinan nyata untuk menyembunyikan bug.
Sekarang, jika modul bar memiliki atribut "
os
", "mystuff
", dll ..., mereka akan menimpa yang diimpor secara eksplisit, dan mungkin menunjuk ke hal-hal yang sangat berbeda. Mendefinisikan__all__
bar seringkali bijaksana - ini menyatakan apa yang akan diimpor secara implisit - tetapi masih sulit untuk melacak dari mana objek berasal, tanpa membaca dan menguraikan modul bar dan mengikuti nya impor. Jaringanimport *
adalah hal pertama yang saya perbaiki ketika saya memiliki sebuah proyek.Jangan salah paham: jika
import *
hilang, saya akan menangis untuk memilikinya. Tetapi harus digunakan dengan hati-hati. Kasus penggunaan yang baik adalah untuk menyediakan antarmuka fasad di atas modul lain. Demikian juga, penggunaan pernyataan impor bersyarat, atau impor di dalam ruang nama fungsi / kelas, memerlukan sedikit disiplin.Saya pikir dalam proyek-proyek menengah ke besar, atau yang kecil dengan beberapa kontributor, kebersihan minimum diperlukan dalam hal analisis statis - menjalankan setidaknya pyflakes atau bahkan lebih baik pylint yang dikonfigurasi dengan benar - untuk menangkap beberapa jenis bug sebelum itu terjadi.
Tentu saja karena ini adalah python - jangan ragu untuk melanggar aturan, dan untuk mengeksplorasi - tetapi waspada terhadap proyek yang dapat tumbuh sepuluh kali lipat, jika kode sumber hilang disiplin maka itu akan menjadi masalah.
sumber
execfile()
. Untungnya, ini jarang digunakan dan hilang dalam 3.x.**vars()
cara memasukkan global jika fungsi yang dipanggil ada di file lain? : PTidak apa-apa untuk dilakukan
from ... import *
dalam sesi interaktif.sumber
doctest
string? Apakahimport *
ditafsirkan dalam "kotak pasir" dalam kasus ini? Terima kasih.Itu karena Anda mencemari namespace. Anda akan mengimpor semua fungsi dan kelas di namespace Anda sendiri, yang mungkin berbenturan dengan fungsi yang Anda tentukan sendiri.
Lebih jauh, saya pikir menggunakan nama yang berkualifikasi lebih jelas untuk tugas pemeliharaan; Anda melihat pada baris kode itu sendiri dari mana fungsi berasal, sehingga Anda dapat memeriksa dokumen dengan lebih mudah.
Dalam modul foo:
Dalam kode Anda:
sumber
http://docs.python.org/tutorial/modules.html
sumber
Katakanlah Anda memiliki kode berikut dalam modul bernama foo:
dan kemudian dalam modul Anda sendiri, Anda memiliki:
Anda sekarang memiliki modul sulit-untuk-debug yang sepertinya memiliki lxml's etree di dalamnya, tetapi sebenarnya memiliki ElementTree sebagai gantinya.
sumber
Ini semua adalah jawaban yang bagus. Saya akan menambahkan bahwa ketika mengajar orang baru kode dengan Python, berurusan dengan
import *
sangat sulit. Bahkan jika Anda atau mereka tidak menulis kode, itu masih merupakan batu sandungan.Saya mengajar anak-anak (sekitar 8 tahun) untuk memprogram dengan Python untuk memanipulasi Minecraft. Saya ingin memberi mereka lingkungan pengkodean yang bermanfaat untuk bekerja dengan ( Editor Atom ) dan mengajarkan pengembangan yang digerakkan oleh REPL (via bpython ). Dalam Atom saya menemukan bahwa petunjuk / penyelesaian berfungsi sama efektifnya dengan bpython. Untungnya, tidak seperti beberapa alat analisis statistik lainnya, Atom tidak tertipu
import *
.Namun, mari kita ambil contoh ini ... Dalam pembungkus ini mereka
from local_module import *
memiliki banyak modul termasuk daftar blok ini . Mari kita abaikan risiko tabrakan namespace. Dengan melakukan itufrom mcpi.block import *
mereka membuat seluruh daftar jenis blok yang tidak jelas ini sesuatu yang harus Anda perhatikan untuk mengetahui apa yang tersedia. Jika mereka malah digunakanfrom mcpi import block
, maka Anda bisa mengetikwalls = block.
dan kemudian daftar autocomplete akan muncul.sumber
Memahami poin yang valid yang diletakkan orang di sini. Namun, saya punya satu argumen yang, kadang-kadang, "impor bintang" tidak selalu menjadi praktik yang buruk:
const.py
:import const
, maka untuk setiap konstanta, saya harus menyebutnya sebagaiconst.SOMETHING
, yang mungkin bukan cara yang paling nyaman.from const import SOMETHING_A, SOMETHING_B ...
, maka jelas itu terlalu bertele-tele dan mengalahkan tujuan penataan.from const import *
mungkin pilihan yang lebih baik.sumber
Ini adalah praktik yang sangat buruk karena dua alasan:
Untuk poin 1 : Mari kita lihat contoh ini:
Di sini, saat melihat kode tidak ada yang akan mendapatkan ide tentang dari modul mana
b
,c
dand
sebenarnya milik.Di sisi lain, jika Anda suka:
Ini jauh lebih bersih untuk Anda, dan orang baru yang bergabung dengan tim Anda akan memiliki ide yang lebih baik.
Untuk poin 2 : Misalkan keduanya
module1
danmodule2
memiliki variabel sebagaib
. Ketika saya melakukannya:Di sini nilai dari
module1
hilang. Akan sulit untuk men-debug mengapa kode tidak berfungsi meskipunb
dinyatakan dalammodule1
dan saya telah menulis kode yang mengharapkan kode saya untuk digunakanmodule1.b
Jika Anda memiliki variabel yang sama di modul yang berbeda, dan Anda tidak ingin mengimpor seluruh modul, Anda bahkan dapat melakukan:
sumber
Sebagai tes, saya membuat module test.py dengan 2 fungsi A dan B, yang masing-masing mencetak "A 1" dan "B 1". Setelah mengimpor test.py dengan:
. . . Saya dapat menjalankan 2 fungsi sebagai test.A () dan test.B (), dan "test" muncul sebagai modul di namespace, jadi jika saya mengedit test.py saya dapat memuatnya kembali dengan:
Tetapi jika saya melakukan hal berikut:
tidak ada referensi untuk "test" di namespace, jadi tidak ada cara untuk memuatnya kembali setelah diedit (sejauh yang saya tahu), yang merupakan masalah dalam sesi interaktif. Sedangkan salah satu dari yang berikut:
akan menambahkan "test" atau "tt" (masing-masing) sebagai nama modul di namespace, yang akan memungkinkan memuat ulang.
Jika aku melakukan:
nama "A" dan "B" muncul di namespace sebagai fungsi . Jika saya mengedit test.py, dan mengulangi perintah di atas, versi fungsi yang dimodifikasi tidak dimuat ulang.
Dan perintah berikut ini memunculkan pesan kesalahan.
Jika seseorang tahu cara memuat ulang modul yang memuat "from module import *", silakan kirim. Kalau tidak, ini akan menjadi alasan lain untuk menghindari formulir:
sumber
Seperti yang disarankan dalam dokumen, Anda sebaiknya (hampir) tidak pernah menggunakan
import *
kode produksi.Meskipun mengimpor
*
dari modul buruk, mengimpor * dari suatu paket bahkan lebih buruk. Secara default,from package import *
mengimpor nama apa pun yang ditentukan oleh paket__init__.py
, termasuk semua submodul dari paket yang dimuat sebelumnyaimport
pernyataan .Namun, jika
__init__.py
kode paket mendefinisikan daftar bernama__all__
, itu diambil sebagai daftar nama submodule yang harus diimpor ketikafrom package import *
ditemui.Pertimbangkan contoh ini (dengan asumsi tidak ada
__all__
definisi dalamsound/effects/__init__.py
):Pernyataan terakhir akan mengimpor
echo
dansurround
modul ke namespace saat ini (mungkin mengesampingkan definisi sebelumnya) karena mereka didefinisikan dalamsound.effects
paket ketikaimport
pernyataan dieksekusi.sumber