Pourquoi “import *” mauvaise?
Il est recommandé de ne pas utiliser import *
en Python.
Quelqu'un peut s'il vous plaît partager la raison, de sorte que je peux éviter de le faire la prochaine fois?
- Dupliquer: stackoverflow.com/questions/2360724/...
- cela dépend si vous êtes de script ou de l'écriture de code que vous devez réutiliser. il paie parfois à ignorer les normes du code. "import *" peut aussi être très bien si vous avez une convention de nommage qui permet de savoir exactement des choses est venu de. par exemple, "les Chats d'importation *; TabbyCat; MaineCoonCat; CalicoCat;"
import *
ne fonctionne pas pour moi en premier lieu en Python 2 ou 3.
Vous devez vous connecter pour publier un commentaire.
Car il met beaucoup de choses dans votre espace de noms (peut-ombre un autre objet à partir d'importation précédent et vous ne savez pas à ce sujet).
Parce que vous ne savez pas exactement ce qui est importé et ne peuvent pas facilement trouver à partir de laquelle le module a certaine chose a été importé (lisibilité).
Parce que vous ne pouvez pas utiliser des outils fraîche comme
pyflakes
statiquement détecter des erreurs dans votre code.numpy.any
ombrageany
quand ils nefrom numpy import *
ou un "utiles", l'outil fait pour eux.import *
fait le commander de laimport
consolidés principales... même pour la bibliothèque standard les modules qui ne sont pas normalement des soins sur l'importation de l'ordre. Quelque chose d'aussi innocent que le classement en ordre alphabétique votreimport
états pourraient briser votre script lorsqu'un ex-victime de l'importation de la guerre devient le seul survivant. (Même si votre script fonctionne maintenant et ne change jamais, il pourrait échouer subitement quelque temps plus tard, si le module importé introduit un nouveau nom qui remplace un vous avez été en s'appuyant sur.)Selon la Zen de Python:
... ne peut pas argumenter avec ça, sûrement?
auto
, dont je suis un grand fan de. Même si c'est redondant trop 🙂use strict
(JavaScriptvar
). En aparté, de cours Python est pas sans type (c'est en fait fortement typé). De toute façon, même si vous avez raison, il serait encore en contradiction avec la Zen de Python, cité dans cette réponse.Vous ne passez pas
**locals()
de fonctions, avez-vous?Depuis le Python n'a pas de "comprendre" déclaration, et la
self
paramètre est explicite, et portée règles sont assez simples, il est généralement très facile de pointer du doigt une variable et de dire d'où que l'objet vient de passer de la lecture à d'autres modules et sans aucune sorte d'IDE (qui sont limitées dans la voie de l'introspection, de toute façon, par le fait que la langue est très dynamique).La
import *
des sauts de tout cela.Aussi, il a une possibilité concrète de se cacher de bugs.
Maintenant, si le module de barre a tout de la "
os
", "mystuff
", etc... les attributs, ils remplacent de façon explicite pour ceux qui sont importés, et peut-être à des choses très différentes. La définition de__all__
dans le bar est souvent sage-cette les etats ce sera implicitement être importé, mais il est encore difficile de retrouver la trace où les objets viennent, sans la lecture et de l'analyse du module de barre et à la suite de son importations. Un réseau deimport *
est la première chose que j'ai corrigé quand je prends l'appropriation d'un projet.Ne vous méprenez pas: si le
import *
avaient disparus, j'ai envie de pleurer pour l'avoir. Mais il doit être utilisé avec précaution. Un bon cas d'utilisation est de fournir une façade interface sur un autre module.De même, l'utilisation de la réserve de déclarations d'importation, ou les importations à l'intérieur de la fonction/classe d'espaces de noms, demande un peu de discipline.
Je pense que dans un milieu à de grands projets, ou les petits, avec plusieurs contributeurs, un minimum d'hygiène est nécessaire en termes de statique -- analyse de la course au moins pyflakes ou encore mieux, un correctement configuré pylint -- à attraper plusieurs genre de bugs avant qu'ils ne surviennent.
Bien sûr, puisque c'est python-n'hésitez pas à briser les règles, et d'explorer -- mais méfiez-vous des projets qui pourraient être décuplées, si le code source est manquante de la discipline, il ne sera pas un problème.
execfile()
. Heureusement, il est rarement utilisé et disparu en 3.x.**vars()
inclure globals si la fonction appelée est dans un autre fichier? 😛C'est parce que vous êtes de polluer l'espace de noms. Vous allez importer toutes les fonctions et les classes dans votre propre espace de noms, ce qui peut entrer en conflit avec les fonctions que vous définissez vous-même.
En outre, je pense que l'utilisation d'un nom qualifié est plus clair pour les tâches de maintenance; vous voyez sur la ligne de code où une fonction, donc vous pouvez consulter les docs beaucoup plus facilement.
Dans le module foo:
Dans votre code:
Il est OK pour faire
from ... import *
dans une session interactive.http://docs.python.org/tutorial/modules.html
Dire que vous avez le code suivant dans un module appelé foo:
et puis dans votre propre module, vous avez:
Vous avez maintenant difficile à déboguer module ressemble il a lxml du programme etree, mais vraiment a ElementTree à la place.
Ce sont toutes de bonnes réponses. Je vais ajouter que lors de l'enseignement de nouvelles personnes de code en Python, traiter avec
import *
est très difficile. Même si vous ou qu'ils n'ont pas écrit le code, c'est toujours une pierre d'achoppement.J'enseigne aux enfants (environ 8 ans) pour la programmation en Python pour manipuler Minecraft. Je tiens à leur donner un utile de codage de l'environnement de travail avec (L'Atome De L'Éditeur) et d'enseigner REPL-driven development (via bpython). Dans l'Atome, je trouve que les conseils/d'achèvement fonctionne tout aussi efficacement que bpython. Heureusement, contrairement à d'autres outils d'analyse statistiques, l'Atome n'est pas dupe par
import *
.Cependant, permet de prendre cet exemple... Dans ce wrapper ils
from local_module import *
un tas de modules, y compris cette liste de blocs. Nous allons ignorer le risque de collisions d'espace de noms. En faisantfrom mcpi.block import *
à faire de cet ensemble de la liste des obscurs types de blocs quelque chose que vous avez à aller chercher à savoir ce qui est disponible. Si ils avaient plutôt utiliséfrom mcpi import block
, alors vous pourriez typewalls = block.
et ensuite une liste de saisie semi-pop up.Compris les points valides, les gens mettent ici. Cependant, j'ai un argument qui, parfois, des étoiles "importer" peut ne pas être une mauvaise pratique:
const.py
:import const
, puis pour chaque constante, je dois le renvoyer commeconst.SOMETHING
, qui n'est probablement pas le moyen le plus pratique.from const import SOMETHING_A, SOMETHING_B ...
, alors évidemment, c'est beaucoup trop verbeux et de défaites le but de la structuration.from const import *
peut être un meilleur choix.C'est un très MAUVAIS pratique pour deux raisons:
Pour point 1:
Voyons un exemple:
Ici, sur voir le code pas à l'idée en ce qui concerne à partir de laquelle le module de
b
,c
etd
appartient réellement.Sur l'autre sens, si vous le faites comme:
C'est beaucoup plus propre pour vous et aussi de la nouvelle personne de me joindre à votre équipe vous avez une meilleure idée.
Pour point 2: disons que les deux
module1
etmodule2
variable commeb
. Quand je fais:Ici la valeur de
module1
est perdu. Il va être difficile à déboguer pourquoi le code ne fonctionne pas, même sib
est déclaré dansmodule1
et j'ai écrit le code attend mon code pour utilisermodule1.b
Si vous disposez des mêmes variables dans les différents modules, et que vous ne souhaitez pas importer tout le module, vous pouvez même le faire:
Comme un test, j'ai créé un module test.py avec 2 fonctions A et B, qui sont respectivement imprimer Un "1" et "B 1". Après l'importation test.py avec:
. . . Je peux courir le 2 fonctions en tant que test.Un() et de test.B(), et "test" s'affiche comme un module dans l'espace de noms, donc si j'ai éditer test.py je peux le recharger avec:
Mais si je ne les suivants:
il n'y a pas de référence à "test" dans l'espace de noms, il n'existe aucun moyen de la recharger après une modification (autant que je puisse dire), qui est un problème dans une session interactive. Alors que l'une des conditions suivantes:
permettra d'ajouter "test" ou "tt" (respectivement) que les noms de module dans l'espace de noms, ce qui vous permettra de re-chargement.
Si je fais:
les noms de "A" et "B" afficher dans l'espace de fonctions. Si j'ai éditer test.py et répétez la commande ci-dessus, les versions modifiées des fonctions n'obtenez pas rechargé.
Et la commande suivante provoque un message d'erreur.
Si quelqu'un sait comment recharger un module chargé avec "from module import *", s'il vous plaît poster. Sinon, ce serait une autre raison d'éviter la forme:
Comme suggéré dans les docs, vous ne devez jamais utiliser
import *
dans le code de production.Lors de l'importation
*
à partir d'un module est mauvais, l'importation * à partir d'un package est encore pire. Fondamentalement,from package import *
les importations quelle que soit les noms sont définis par le paquet__init__.py
, mais il comprend aussi toutes les submodules de l'emballage qui ont été chargés par les précédentsimport
consolidés.Considérons cet exemple:
La dernière déclaration de l'importation de la
echo
etsurround
modules dans l'espace de noms courant (en surchargeant définitions précédentes) parce qu'ils sont définis dans lesound.effects
package lors de laimport
instruction est exécutée.