Si consiglia di non utilizzare import *
in Python.
Qualcuno può condividere il motivo di ciò, in modo da poterlo evitare la prossima volta?
import *
non funziona per me in primo luogo in Python 2 o 3.
Si consiglia di non utilizzare import *
in Python.
Qualcuno può condividere il motivo di ciò, in modo da poterlo evitare la prossima volta?
import *
non funziona per me in primo luogo in Python 2 o 3.
Risposte:
Perché mette molte cose nel tuo spazio dei nomi (potrebbe oscurare qualche altro oggetto dalla precedente importazione e non lo saprai).
Perché non sai esattamente cosa viene importato e non puoi facilmente trovare da quale modulo è stata importata una certa cosa (leggibilità).
Perché non puoi usare strumenti interessanti come pyflakes
rilevare staticamente errori nel tuo codice.
numpy.any
dall'ombra any
quando lo fanno from numpy import *
o uno strumento "utile" lo fa per loro.
import *
rende significativo l' ordine delle import
istruzioni ... anche per i moduli di libreria standard che normalmente non si preoccupano dell'ordine di importazione . Qualcosa di innocente come l'alfabetizzazione delle tue import
dichiarazioni potrebbe rompere la tua sceneggiatura quando un'ex vittima della guerra di importazione diventa l'unico sopravvissuto. (Anche se il tuo script funziona ora e non cambia mai, potrebbe improvvisamente fallire qualche tempo dopo se il modulo importato introduce un nuovo nome che sostituisce quello su cui stavi facendo affidamento.)
use strict
(JavaScript var
). A parte questo, ovviamente Python non è senza tipo (in realtà è fortemente tipizzato). Comunque, anche se avessi ragione, ciò contraddirebbe comunque lo Zen di Python, citato in questa risposta.
Non passi **locals()
alle funzioni, vero?
Poiché Python manca di un'istruzione "include" e il self
parametro è esplicito e le regole di scoping sono piuttosto semplici, di solito è molto facile puntare un dito su una variabile e dire da dove proviene quell'oggetto - senza leggere altri moduli e senza alcun tipo di IDE (che sono comunque limitati in termini di introspezione, dal fatto che il linguaggio è molto dinamico).
Tutto ciò import *
rompe.
Inoltre, ha una concreta possibilità di nascondere bug.
import os, sys, foo, sqlalchemy, mystuff
from bar import *
Ora, se il modulo bar ha uno degli attributi " os
", " mystuff
", ecc ..., sovrascriveranno quelli esplicitamente importati e probabilmente indicheranno cose molto diverse. Definire __all__
nel bar è spesso saggio - questo afferma ciò che implicitamente essere importati - ma ancora è difficile rintracciare in cui gli oggetti provengono, senza leggere e analisi del modulo di bar e seguendo le sue importazioni. Una rete di import *
è la prima cosa che risolvo quando divento la proprietà di un progetto.
Non fraintendermi: se import *
mancassero, piangerei per averlo. Ma deve essere usato con cura. Un buon caso d'uso è fornire un'interfaccia di facciata su un altro modulo. Allo stesso modo, l'uso di istruzioni di importazione condizionali o importazioni all'interno di spazi dei nomi di funzioni / classi richiede un po 'di disciplina.
Penso che in progetti medio-grandi, o piccoli con diversi partecipanti, sia necessario un minimo di igiene in termini di analisi statica - eseguendo almeno pyflakes o ancora meglio un pilastro correttamente configurato - per catturare diversi tipi di bug prima accadono.
Ovviamente dato che si tratta di Python - sentiti libero di infrangere le regole e di esplorare - ma fai attenzione ai progetti che potrebbero crescere di dieci volte, se al codice sorgente manca la disciplina sarà un problema.
execfile()
. Fortunatamente, è raramente usato e andato in 3.x.
**vars()
di includere globali se la funzione chiamata si trova in un altro file? : P
Questo perché stai inquinando lo spazio dei nomi. Importerai tutte le funzioni e le classi nel tuo spazio dei nomi, che potrebbe scontrarsi con le funzioni che definisci tu stesso.
Inoltre, penso che l'uso di un nome qualificato sia più chiaro per l'attività di manutenzione; nella riga di codice viene visualizzato da dove proviene una funzione, in modo da poter consultare i documenti molto più facilmente.
Nel modulo foo:
def myFunc():
print 1
Nel tuo codice:
from foo import *
def doThis():
myFunc() # Which myFunc is called?
def myFunc():
print 2
http://docs.python.org/tutorial/modules.html
Si noti che in generale la pratica dell'importazione
*
da un modulo o pacchetto è disapprovata, poiché spesso causa codice scarsamente leggibile .
Queste sono tutte buone risposte. Aggiungo che quando si insegna a nuove persone a scrivere codice in Python, import *
è molto difficile occuparsene . Anche se tu o loro non avete scritto il codice, è ancora un ostacolo.
Insegno ai bambini (circa 8 anni) a programmare in Python per manipolare Minecraft. Mi piace offrire loro un utile ambiente di codifica con cui lavorare ( Atom Editor ) e insegnare lo sviluppo guidato da REPL (tramite bpython ). In Atom trovo che i suggerimenti / completamenti funzionino altrettanto efficacemente di bpython. Fortunatamente, a differenza di altri strumenti di analisi statistica, Atom non viene ingannato import *
.
Comunque, facciamo questo esempio ... In questo wrapper hanno from local_module import *
un sacco di moduli incluso questo elenco di blocchi . Ignoriamo il rischio di collisioni dello spazio dei nomi. In questo from mcpi.block import *
modo rendono l'intero elenco di tipi oscuri di blocchi qualcosa che devi andare a vedere per sapere cosa è disponibile. Se invece lo avessero usato from mcpi import block
, allora potevi digitare walls = block.
e quindi comparirà un elenco di completamento automatico.
Compresi i punti validi che la gente mette qui. Tuttavia, ho un argomento secondo cui, a volte, "l'importazione da stelle" potrebbe non essere sempre una cattiva pratica:
const.py
:
import const
, quindi per ogni costante, devo riferirlo come const.SOMETHING
, che probabilmente non è il modo più conveniente.from const import SOMETHING_A, SOMETHING_B ...
, allora ovviamente è troppo prolisso e sconfigge lo scopo della strutturazione.from const import *
potrebbe essere una scelta migliore.È una pratica molto CATTIVA per due motivi:
Per il punto 1 : vediamo un esempio di questo:
from module1 import *
from module2 import *
from module3 import *
a = b + c - d
Qui, vedendo il codice, nessuno avrà idea di quale modulo b
, c
ed
in realtà appartiene.
D'altra parte, se lo fai come:
# 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
È molto più pulito per te e anche la nuova persona che si unisce al tuo team avrà un'idea migliore.
Per il punto 2 : diciamo entrambi module1
e module2
hanno una variabile come b
. Quando io faccio:
from module1 import *
from module2 import *
print b # will print the value from module2
Qui il valore da module1
viene perso. Sarà difficile eseguire il debug del motivo per cui il codice non funziona anche se b
viene dichiarato in module1
e ho scritto il codice in attesa del mio codice da utilizzaremodule1.b
Se hai le stesse variabili in moduli diversi e non vuoi importare l'intero modulo, puoi anche fare:
from module1 import b as mod1b
from module2 import b as mod2b
Come test, ho creato un modulo test.py con 2 funzioni A e B, che stampano rispettivamente "A 1" e "B 1". Dopo aver importato test.py con:
import test
. . . Posso eseguire le 2 funzioni come test.A () e test.B () e "test" si presenta come un modulo nello spazio dei nomi, quindi se modifico test.py posso ricaricarlo con:
import importlib
importlib.reload(test)
Ma se faccio quanto segue:
from test import *
non c'è alcun riferimento a "test" nello spazio dei nomi, quindi non c'è modo di ricaricarlo dopo una modifica (per quanto posso dire), che è un problema in una sessione interattiva. Considerando che uno dei seguenti:
import test
import test as tt
aggiungerà "test" o "tt" (rispettivamente) come nomi dei moduli nello spazio dei nomi, il che consentirà il nuovo caricamento.
Se lo faccio:
from test import *
i nomi "A" e "B" vengono visualizzati nello spazio dei nomi come funzioni . Se modifico test.py e ripeto il comando precedente, le versioni modificate delle funzioni non vengono ricaricate.
E il seguente comando genera un messaggio di errore.
importlib.reload(test) # Error - name 'test' is not defined
Se qualcuno sa come ricaricare un modulo caricato con "from module import *", si prega di inviare. Altrimenti, questo sarebbe un altro motivo per evitare il modulo:
from module import *
Come suggerito nei documenti, non dovresti (quasi) mai usare import *
nel codice di produzione.
Mentre l'importazione *
da un modulo è negativa, l' importazione * da un pacchetto è ancora peggio. Per impostazione predefinita, from package import *
importa tutti i nomi definiti dai pacchetti __init__.py
, inclusi eventuali sottomoduli del pacchetto caricati in precedenzaimport
istruzioni .
Tuttavia, se il __init__.py
codice di un pacchetto definisce un elenco denominato __all__
, viene considerato l'elenco dei nomi dei sottomoduli che devono essere importati quando from package import *
viene rilevato.
Considera questo esempio (supponendo che non sia __all__
definito in 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 *
L'ultima istruzione importerà i moduli echo
e surround
nello spazio dei nomi corrente (possibilmente sovrascrivendo le definizioni precedenti) perché sono definiti nel sound.effects
pacchetto quando import
viene eseguita l' istruzione.