É recomendável não usar import *
no Python.
Alguém pode compartilhar o motivo disso, para que eu possa evitar isso da próxima vez?
python
python-import
Entusiasta de software
fonte
fonte
import *
não funciona para mim em primeiro lugar no Python 2 ou 3.Respostas:
Porque coloca um monte de coisas no seu espaço para nome (pode ocultar outro objeto da importação anterior e você não o saberá).
Porque você não sabe exatamente o que é importado e não consegue encontrar facilmente de qual módulo uma determinada coisa foi importada (legibilidade).
Porque você não pode usar ferramentas legais, como
pyflakes
detectar estaticamente erros no seu código.fonte
numpy.any
sombraany
quando o fazemfrom numpy import *
ou uma ferramenta "útil" faz isso por eles.import *
torna a ordem dasimport
instruções significativa ... mesmo para os módulos de biblioteca padrão que normalmente não se importam com a ordem de importação . Algo tão inocente quanto colocar em ordem alfabética suasimport
declarações pode quebrar seu script quando uma ex-vítima da guerra de importação se torna o único sobrevivente. (Mesmo que o seu script funciona agora e nunca muda, pode falhar de repente em algum momento mais tarde, se as introduz módulo importado um novo nome que substitui um você estava contando com.)De acordo com o Zen de Python :
... não posso discutir com isso, com certeza?
fonte
use strict
(JavaScriptvar
). Como um aparte, é claro que o Python não é digitado (na verdade, é fortemente tipado). De qualquer forma, mesmo se você estivesse certo, isso ainda contradiz o Zen de Python, citado nesta resposta.Você não passa
**locals()
para funções, não é?Como o Python não possui uma instrução "include" e o
self
parâmetro é explícito, e regras de escopo são bastante simples, geralmente é muito fácil apontar um dedo para uma variável e dizer de onde vem esse objeto - sem ler outros módulos e sem nenhum tipo do IDE (que de qualquer maneira é limitado na introspecção, pelo fato de a linguagem ser muito dinâmica).o
import *
quebra tudo isso.Além disso, tem uma possibilidade concreta de ocultar bugs.
Agora, se o módulo de barra tiver alguma das "
os
mystuff
atributos ", " ", etc ..., eles substituirão os importados explicitamente e possivelmente apontarão para coisas muito diferentes. A definição__all__
de barra é geralmente sábia - isso indica o que implicitamente será importado - mas ainda é difícil rastrear a origem dos objetos, sem ler e analisar o módulo de barras e seguir suas importações. Uma rede deimport *
é a primeira coisa que conserto quando me aproprio de um projeto.Não me entenda mal: se
import *
faltava, eu choraria por tê-lo. Mas tem que ser usado com cuidado. Um bom caso de uso é fornecer uma interface de fachada sobre outro módulo. Da mesma forma, o uso de instruções de importação condicionais, ou importações dentro de namespaces de função / classe, requer um pouco de disciplina.Eu acho que em projetos de médio a grande porte ou pequenos com vários colaboradores, é necessária uma higiene mínima em termos de análise estática - executando pelo menos flocos de neve ou, melhor ainda, um pylint configurado corretamente - para capturar vários tipos de erros antes eles acontecem.
É claro que, como se trata de python - sinta-se à vontade para violar regras e explorar -, mas tenha cuidado com projetos que podem crescer dez vezes, se o código-fonte estiver com falta de disciplina, será um problema.
fonte
execfile()
. Felizmente, raramente é usado e usado no 3.x.**vars()
incluir globais se a função chamada estiver em outro arquivo? : PNão há problema em fazer
from ... import *
uma sessão interativa.fonte
doctest
corda? Oimport *
interpretado dentro de uma "caixa de areia" neste caso? Obrigado.Isso é porque você está poluindo o espaço para nome. Você importará todas as funções e classes em seu próprio espaço para nome, o que pode colidir com as funções que você mesmo define.
Além disso, acho que usar um nome qualificado é mais claro para a tarefa de manutenção; você vê na própria linha de código de onde vem uma função, para que você possa conferir os documentos com muito mais facilidade.
No módulo foo:
No seu código:
fonte
http://docs.python.org/tutorial/modules.html
fonte
Digamos que você tenha o seguinte código em um módulo chamado foo:
e então em seu próprio módulo você tem:
Agora você tem um módulo difícil de depurar, que parece ter o lreex etree, mas realmente possui o ElementTree.
fonte
Todas essas são boas respostas. Vou acrescentar que, ao ensinar novas pessoas a codificar em Python, lidar com
import *
é muito difícil. Mesmo se você ou eles não escreveram o código, ainda é um obstáculo.Eu ensino crianças (cerca de 8 anos) a programar em Python para manipular o Minecraft. Eu gosto de oferecer a eles um ambiente de codificação útil para trabalhar com ( Atom Editor ) e ensinar desenvolvimento orientado a REPL (via bpython ). No Atom, acho que as dicas / conclusão funcionam tão eficientemente quanto o bpython. Felizmente, ao contrário de outras ferramentas de análise estatística, o Atom não se deixa enganar
import *
.No entanto, vamos dar este exemplo ... Neste wrapper, eles
from local_module import *
agrupam vários módulos, incluindo esta lista de blocos . Vamos ignorar o risco de colisões de namespace. Ao fazer isso,from mcpi.block import *
eles fazem dessa lista inteira de tipos obscuros de blocos algo que você deve procurar para saber o que está disponível. Se eles tivessem usadofrom mcpi import block
, você poderia digitarwalls = block.
e uma lista de preenchimento automático apareceria.fonte
Entendeu os pontos válidos que as pessoas colocam aqui. No entanto, tenho um argumento de que, às vezes, "importação em estrela" nem sempre pode ser uma prática ruim:
const.py
:import const
, então, para cada constante, tenho que referir comoconst.SOMETHING
, o que provavelmente não é a maneira mais conveniente.from const import SOMETHING_A, SOMETHING_B ...
, obviamente é muito detalhado e derrota o objetivo da estruturação.from const import *
pode ser uma escolha melhor.fonte
É uma prática muito ruim por duas razões:
Para o ponto 1 : vamos ver um exemplo disso:
Aqui, ao ver o código ninguém vai ter idéia a respeito de qual módulo
b
,c
ed
na verdade pertence.Por outro lado, se você fizer o seguinte:
É muito mais limpo para você, e também a nova pessoa que se juntará à sua equipe terá uma ideia melhor.
Para o ponto 2 : Digamos ambos
module1
emodule2
tenha variável comob
. Quando eu faço:Aqui o valor de
module1
é perdido. Será difícil depurar por que o código não está funcionando, mesmo queb
seja declaradomodule1
e eu escrevi o código esperando que meu código fosse usadomodule1.b
Se você possui as mesmas variáveis em módulos diferentes e não deseja importar o módulo inteiro, pode até fazer:
fonte
Como teste, criei um módulo test.py com 2 funções A e B, que imprimem respectivamente "A 1" e "B 1". Após importar o test.py com:
. . . Eu posso executar as 2 funções como test.A () e test.B () e "test" aparece como um módulo no espaço para nome; portanto, se eu editar test.py, posso recarregá-lo com:
Mas se eu fizer o seguinte:
não há referência a "teste" no espaço para nome; portanto, não há como recarregá-lo após uma edição (pelo que sei), o que é um problema em uma sessão interativa. Considerando que um dos seguintes:
adicionará "test" ou "tt" (respectivamente) como nomes de módulo no espaço para nome, o que permitirá o recarregamento.
Se eu fizer:
os nomes "A" e "B" aparecem no espaço para nome como funções . Se eu editar test.py e repetir o comando acima, as versões modificadas das funções não serão recarregadas.
E o comando a seguir gera uma mensagem de erro.
Se alguém souber recarregar um módulo carregado com "from module import *", poste. Caso contrário, esse seria outro motivo para evitar o formulário:
fonte
Conforme sugerido nos documentos, você nunca deve (quase) usar
import *
no código de produção.Embora a importação
*
de um módulo seja ruim, a importação * de um pacote é ainda pior. Por padrão,from package import *
importa quaisquer nomes que sejam definidos pelos pacotes__init__.py
, incluindo quaisquer submódulos do pacote carregados por versões anteriores.import
instruções .No entanto, se o
__init__.py
código de um pacote definir uma lista denominada__all__
, será considerada a lista de nomes de sub-módulos que devem ser importados quandofrom package import *
encontrados.Considere este exemplo (supondo que não haja um
__all__
definido emsound/effects/__init__.py
):A última instrução importará os módulos
echo
esurround
no espaço para nome atual (possivelmente substituindo as definições anteriores) porque elas são definidas nosound.effects
pacote quando aimport
instrução é executada.fonte