import *
Python'da kullanmamanız önerilir .
Bir dahaki sefere yapmaktan kaçınabilmek için bunun nedenini herkes paylaşabilir mi?
import *
Python 2 veya 3'te ilk olarak benim için çalışmıyor
import *
Python'da kullanmamanız önerilir .
Bir dahaki sefere yapmaktan kaçınabilmek için bunun nedenini herkes paylaşabilir mi?
import *
Python 2 veya 3'te ilk olarak benim için çalışmıyor
Yanıtlar:
Ad alanınıza çok fazla şey koyduğundan (önceki içe aktarmadan başka bir nesneyi gölgeleyebilir ve bunu bilmezsiniz).
Çünkü neyin ithal edildiğini tam olarak bilmiyorsunuz ve belirli bir şeyin hangi modülden alındığını kolayca bulamıyorsunuz (okunabilirlik).
Çünkü pyflakes
kodunuzdaki hataları statik olarak saptamak gibi harika araçlar kullanamazsınız .
numpy.any
gölgelendirerek ısırıldı veya "yararlı" bir araç onlar için yapıyor. any
from numpy import *
import *
yapar düzeni içinde import
bile normal ithalat sipariş umurumda değil standart kütüphane modülleri için ... önemli tablolar . İfade import
savaşının eski bir kazası hayatta kalan tek kişi olduğunda ifadelerinizi alfabetik olarak tanımlamak kadar masum bir şey senaryonuzu kırabilir. (Komut dosyanız şimdi çalışıyor ve asla değişmese bile, içe aktarılan modül güvendiğiniz yerin yerini alan yeni bir ad getirirse aniden başarısız olabilir.)
use strict
(JavaScript var
). Bir yana, elbette Python daktilo değil (aslında güçlü bir şekilde yazılmıştır). Neyse, hatta eğer sen haklıydın, bu yine Python Zen ters düşeceğini, bu cevap gösterdi.
**locals()
Fonksiyonlara geçmiyorsun , değil mi?
Python bir "include" deyimi yoksun, yana veself
parametre açık olduğunu ve diğer modülleri okumadan ve her türlü olmaksızın - kapsam kuralları oldukça basittir, bu nesne nereden geldiğini bir değişken bir parmağını işaret ve anlatmak çok kolay genellikle var IDE (yine de içgözlemle sınırlı, dil çok dinamik olduğu için).
import *
Sonları hepsi bu.
Ayrıca, böcekleri gizlemek için somut bir olasılığı vardır.
import os, sys, foo, sqlalchemy, mystuff
from bar import *
Şimdi, çubuk modülünde " os
", " mystuff
" vb. Niteliklerin herhangi biri varsa, açıkça içe aktarılanları geçersiz kılar ve muhtemelen çok farklı şeylere işaret ederler. Tanımlanması __all__
örtük olarak ithal edilecek bu ne devletler - - barda akıllıca genellikle ancak nesneler okuma ve çubuk modülü ayrıştırma ve takip etmeden, nereden geldiğini hala iz zor olan ithalatı. Bir ağ, import *
bir projenin sahipliğini aldığımda ilk düzelttiğim şey.
Beni yanlış anlama: eğer import *
eksik olsaydı, sahip olmak için ağlardım. Ancak dikkatli kullanılmalıdır. İyi bir kullanım örneği, başka bir modül üzerinde bir cephe arayüzü sağlamaktır. Benzer şekilde, koşullu içe aktarma ifadelerinin veya işlev / sınıf ad alanları içinde içe aktarma işlemlerinin kullanılması biraz disiplin gerektirir.
Orta ila büyük projelerde veya birkaç katkısı olan küçük projelerde, daha önce birkaç tür hatayı yakalamak için statik analiz açısından en az hijyen gereklidir - en azından pyflakes veya daha iyi düzgün yapılandırılmış bir pylint çalıştırmak - olurlar.
Tabii ki bu python olduğundan - kuralları çiğnemekten ve keşfetmekten çekinmeyin - ancak on kat büyüyebilecek projelere karşı dikkatli olun, eğer kaynak kod disiplini eksikse sorun olacaktır.
execfile()
. Neyse ki, nadiren kullanılır ve 3.x'te gitti.
**vars()
Aranan işlev başka bir dosyadaysa globalleri dahil etmeye ne dersiniz ? : P
Çünkü isim alanını kirletiyorsunuz. Kendiniz tanımladığınız işlevlerle çakışabilecek kendi ad alanınızdaki tüm işlevleri ve sınıfları içe aktaracaksınız.
Ayrıca, kalifiye bir adın bakım görevi için daha açık olduğunu düşünüyorum; kod satırında bir işlevin nereden geldiğini görürsünüz, böylece dokümanları daha kolay kontrol edebilirsiniz.
Foo modülünde:
def myFunc():
print 1
Kodunuzda:
from foo import *
def doThis():
myFunc() # Which myFunc is called?
def myFunc():
print 2
http://docs.python.org/tutorial/modules.html
Genel
*
olarak bir modül veya paketten içe aktarma uygulamasının, genellikle kötü okunabilir koda neden olduğu için kaşlarını çattığına dikkat edin .
Bunların hepsi iyi cevaplar. Python'da yeni insanlara kod yazmayı öğretirken, uğraşmanın import *
çok zor olduğunu da ekleyeceğim . Siz veya onlar kodu yazmasa bile, bu hala bir engel.
Çocuklara (yaklaşık 8 yaşında) Minecraft'ı manipüle etmeleri için Python'da program yapmayı öğretiyorum. Onlara ( Atom Editor ) çalışmak ve REPL güdümlü gelişimi ( bpython aracılığıyla ) öğretmek için yardımcı olacak bir kodlama ortamı sağlamayı seviyorum . Atom'da ipuçlarının / tamamlamanın bpython kadar etkili olduğunu düşünüyorum. Neyse ki, diğer bazı istatistiksel analiz araçlarının aksine, Atom tarafından aldanmayın import *
.
Ancak, bu örneği ele alalım ... Bu paketleyicide , bu blok listesinifrom local_module import *
içeren bir demet modülleri . İsim-alanı çarpışma riskini göz ardı edelim. Bunu yaparak , bu belirsiz blokların tüm listesini yapmak için neyin mevcut olduğunu bilmek için gitmeniz gereken bir şey yaparlar. Bunun yerine kullanmışlarsa , yazabilirsiniz ve daha sonra bir otomatik tamamlama listesi açılır.
from mcpi.block import *
from mcpi import block
walls = block.
İnsanların buraya koyduğu geçerli noktaları anladı. Ancak, bazen, "yıldız içe aktarma" her zaman kötü bir uygulama olmayabilir bir argüman var:
const.py
:
import const
, o zaman her sabit için, onu const.SOMETHING
muhtemelen en uygun yol değil olarak ifade etmeliyim .from const import SOMETHING_A, SOMETHING_B ...
, o zaman çok fazla açıktır ve yapılandırmanın amacını yener.from const import *
daha iyi bir seçim olabilir.Bu ise çok kötü iki nedenden dolayı uygulama:
For noktası 1 : Biraz sert geçebilir bu bir örnek görmek:
from module1 import *
from module2 import *
from module3 import *
a = b + c - d
Burada kod görünce kimse modül hangi ilişkin fikir alacak b
, c
ve d
aslında aittir.
Diğer taraftan, eğer bunu yaparsanız:
# 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
Sizin için çok daha temiz ve ayrıca ekibinize katılan yeni kişinin daha iyi fikri olacak.
İçin noktası 2 : Let hem söylemek module1
ve module2
olarak değişken var b
. Ben yaparken:
from module1 import *
from module2 import *
print b # will print the value from module2
Burada gelen değer module1
kaybolur. Eğer kod bile çalışmama nedenini hata ayıklama zor olacak b
deklare edilmediği module1
ve ben kullanım için kodumu bekliyor kod yazdımmodule1.b
Farklı modüllerde aynı değişkenlere sahipseniz ve tüm modülü içe aktarmak istemiyorsanız, şunları da yapabilirsiniz:
from module1 import b as mod1b
from module2 import b as mod2b
Bir test olarak, sırasıyla "A 1" ve "B 1" yazdıran 2 fonksiyon A ve B ile bir test.py modülü oluşturdum. Test.py dosyasını aşağıdakilerle içe aktardıktan sonra:
import test
. . . 2 işlevini test.A () ve test.B () olarak çalıştırabilirim ve "test" ad alanında bir modül olarak görünür , bu yüzden test.py'yi düzenlerseniz yeniden yükleyebilirim:
import importlib
importlib.reload(test)
Ama eğer aşağıdakileri yaparsam:
from test import *
ad alanında "test" için bir referans yoktur, bu nedenle etkileşimli bir oturumda bir sorun olan bir düzenlemeden sonra (anlayabildiğim kadarıyla) yeniden yüklemenin bir yolu yoktur. Halbuki aşağıdakilerden herhangi biri:
import test
import test as tt
ad alanına modül adları olarak "test" veya "tt" (sırasıyla) ekler ve bu da yeniden yüklemeye izin verir.
Eğer yaparsam:
from test import *
"A" ve "B" adları, ad alanında işlev olarak görünür . Test.py dosyasını düzenler ve yukarıdaki komutu tekrarlarsam, işlevlerin değiştirilmiş sürümleri yeniden yüklenmez.
Ve aşağıdaki komut bir hata mesajı verir.
importlib.reload(test) # Error - name 'test' is not defined
Birisi "modül içe aktarma *" ile yüklenen bir modülü nasıl yeniden yükleyeceğini biliyorsa, lütfen gönderin. Aksi takdirde, bu formu önlemek için başka bir neden olacaktır:
from module import *
Dokümanlarda önerildiği gibi, import *
üretim kodunda (neredeyse) asla kullanmamalısınız .
İthal ederken *
bir gelen modül kötü, bir gelen * ithal paketin daha da kötü. Varsayılan olarak, önceki ifadelerle yüklenmiş paketin alt modülleri de dahil olmak üzere from package import *
paketin tanımladığı adları alır .__init__.py
import
Ancak, bir paketin __init__.py
kodu adlı bir liste tanımlarsa , karşılaşıldığında __all__
alınması gereken alt modül adlarının listesi olarak alınır from package import *
.
Bu örneği düşünün ( __all__
içinde tanımlanmış bir varsayım yok 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 *
Son ifade echo
ve deyimleri surround
geçerli ad alanına alır (muhtemelen önceki tanımları geçersiz kılar) çünkü deyim yürütüldüğünde sound.effects
pakette tanımlanırlar import
.