Disarankan untuk tidak menggunakan import *
Python.
Adakah yang bisa berbagi alasan untuk itu, sehingga saya bisa menghindarinya nanti?
import *
tidak bekerja untuk saya di tempat pertama dalam Python 2 atau 3.
Disarankan untuk tidak menggunakan import *
Python.
Adakah yang bisa berbagi alasan untuk itu, sehingga saya bisa menghindarinya nanti?
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.
numpy.any
membayangi any
ketika mereka melakukannya from numpy import *
atau alat "membantu" melakukannya untuk mereka.
import *
membuat urutan dari import
pernyataan yang signifikan ... bahkan untuk modul perpustakaan standar yang biasanya tidak peduli tentang pesanan impor . Sesuatu yang tidak bersalah seperti abjad import
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 :
Eksplisit lebih baik daripada implisit.
... tidak bisa berdebat dengan itu, tentunya?
use strict
(JavaScript var
). 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.
import os, sys, foo, sqlalchemy, mystuff
from bar import *
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. Jaringan import *
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.
execfile()
. Untungnya, ini jarang digunakan dan hilang dalam 3.x.
**vars()
cara memasukkan global jika fungsi yang dipanggil ada di file lain? : P
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:
def myFunc():
print 1
Dalam kode Anda:
from foo import *
def doThis():
myFunc() # Which myFunc is called?
def myFunc():
print 2
http://docs.python.org/tutorial/modules.html
Perhatikan bahwa secara umum praktik mengimpor
*
dari modul atau paket tidak disukai, karena sering menyebabkan kode yang kurang dapat dibaca .
Katakanlah Anda memiliki kode berikut dalam modul bernama foo:
import ElementTree as etree
dan kemudian dalam modul Anda sendiri, Anda memiliki:
from lxml import etree
from foo import *
Anda sekarang memiliki modul sulit-untuk-debug yang sepertinya memiliki lxml's etree di dalamnya, tetapi sebenarnya memiliki ElementTree sebagai gantinya.
Ini semua adalah jawaban yang bagus. Saya akan menambahkan bahwa ketika mengajar orang baru kode dengan Python, berurusan denganimport *
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 tertipuimport *
.
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 itu from 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 digunakan from mcpi import block
, maka Anda bisa mengetik walls = block.
dan kemudian daftar autocomplete akan muncul.
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 sebagai const.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.Ini adalah praktik yang sangat buruk karena dua alasan:
Untuk poin 1 : Mari kita lihat contoh ini:
from module1 import *
from module2 import *
from module3 import *
a = b + c - d
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:
# v v will know that these are from module1
from module1 import b, c # way 1
import module2 # way 2
a = b + c - module2.d
# ^ will know it is from module2
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
dan module2
memiliki variabel sebagai b
. Ketika saya melakukannya:
from module1 import *
from module2 import *
print b # will print the value from module2
Di sini nilai dari module1
hilang. Akan sulit untuk men-debug mengapa kode tidak berfungsi meskipun b
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:
from module1 import b as mod1b
from module2 import b as mod2b
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:
import test
. . . 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:
import importlib
importlib.reload(test)
Tetapi jika saya melakukan hal berikut:
from test import *
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:
import test
import test as tt
akan menambahkan "test" atau "tt" (masing-masing) sebagai nama modul di namespace, yang akan memungkinkan memuat ulang.
Jika aku melakukan:
from test import *
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.
importlib.reload(test) # Error - name 'test' is not defined
Jika seseorang tahu cara memuat ulang modul yang memuat "from module import *", silakan kirim. Kalau tidak, ini akan menjadi alasan lain untuk menghindari formulir:
from module import *
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 ketika from package import *
ditemui.
Pertimbangkan contoh ini (dengan asumsi tidak ada __all__
definisi dalam sound/effects/__init__.py
):
# anywhere in the code before import *
import sound.effects.echo
import sound.effects.surround
# in your module
from sound.effects import *
Pernyataan terakhir akan mengimpor echo
dan surround
modul ke namespace saat ini (mungkin mengesampingkan definisi sebelumnya) karena mereka didefinisikan dalam sound.effects
paket ketika import
pernyataan dieksekusi.