Il est recommandé de ne pas utiliser import *
en Python.
Quelqu'un peut-il s'il vous plaît partager la raison de cela, afin que je puisse éviter de le faire la prochaine fois?
python
python-import
Passionné de logiciels
la source
la source
import *
ne fonctionne pas pour moi en premier lieu dans Python 2 ou 3.Réponses:
Parce qu'il met beaucoup de choses dans votre espace de noms (peut masquer un autre objet de l'importation précédente et vous ne le saurez pas).
Parce que vous ne savez pas exactement ce qui est importé et que vous ne pouvez pas trouver facilement à partir de quel module une certaine chose a été importée (lisibilité).
Parce que vous ne pouvez pas utiliser des outils sympas comme la
pyflakes
détection statique des erreurs dans votre code.la source
numpy.any
observationany
quand ils le fontfrom numpy import *
ou un outil «utile» le fait pour eux.import *
rend l' ordre desimport
instructions significatif ... même pour les modules de bibliothèque standard qui ne se soucient normalement pas de l'ordre d'importation . Quelque chose d'aussi innocent que de classer vosimport
déclarations par ordre alphabétique pourrait briser votre script lorsqu'une ancienne victime de la guerre d'importation devient le seul survivant. (Même si votre script fonctionne maintenant et ne change jamais, il pourrait soudainement échouer un peu plus tard si le module importé introduit un nouveau nom qui remplace celui sur lequel vous vousSelon le Zen de Python :
... vous ne pouvez pas discuter avec ça, sûrement?
la source
use strict
(JavaScriptvar
). En passant , bien sûr, Python n'est pas sans type (il est en fait fortement typé). Quoi qu'il en soit, même si vous aviez raison, cela contredirait toujours le Zen de Python, cité dans cette réponse.Vous ne passez pas
**locals()
aux fonctions, n'est-ce pas ?Comme Python n'a pas d'instruction "include" et que le
self
paramètre est explicite et que les règles de portée sont assez simples, il est généralement très facile de pointer du doigt une variable et de dire d'où vient cet objet - sans lire d'autres modules et sans aucun type d'IDE (qui sont de toute façon limités en termes d'introspection, par le fait que le langage est très dynamique).Le
import *
casse tout ça.En outre, il a une possibilité concrète de cacher des bugs.
Maintenant, si le module de barre a l'un des attributs "
os
", "mystuff
", etc ..., ils remplaceront ceux explicitement importés, et peuvent pointer vers des choses très différentes. Définir__all__
dans bar est souvent sage - cela indique ce qui sera implicitement importé - mais il est toujours difficile de retracer l'origine des objets, sans lire et analyser le module bar et suivre ses importations. Un réseau deimport *
est la première chose que je corrige lorsque je prends possession d'un projet.Ne vous méprenez pas: s'il
import *
manquait, je pleurerais pour l'avoir. Mais il doit être utilisé avec précaution. Un bon cas d'utilisation est de fournir une interface de façade sur un autre module. De même, l'utilisation d'instructions d'importation conditionnelle ou d'importations à l'intérieur d'espaces de noms de fonctions / classes nécessite un peu de discipline.Je pense que dans les projets de taille moyenne à grande, ou les petits avec plusieurs contributeurs, un minimum d'hygiène est nécessaire en termes d'analyse statique - exécutant au moins pyflakes ou encore mieux un pylint correctement configuré - pour attraper plusieurs types de bugs avant ils arrivent.
Bien sûr, étant donné qu'il s'agit de python - n'hésitez pas à enfreindre les règles et à explorer - mais méfiez-vous des projets qui pourraient décupler, si le code source manque de discipline, ce sera un problème.
la source
execfile()
**vars()
d'inclure des globaux si la fonction appelée est dans un autre fichier? : PC'est OK à faire
from ... import *
dans une session interactive.la source
doctest
chaîne? Est-ce que leimport *
est interprété dans un "bac à sable" dans ce cas? Merci.C'est parce que vous polluez l'espace de noms. Vous importerez toutes les fonctions et classes dans votre propre espace de noms, qui peuvent entrer en conflit avec les fonctions que vous définissez vous-même.
De plus, je pense que l'utilisation d'un nom qualifié est plus clair pour la tâche de maintenance; vous voyez sur la ligne de code elle-même d'où vient une fonction, vous pouvez donc consulter les documents beaucoup plus facilement.
Dans le module foo:
Dans votre code:
la source
http://docs.python.org/tutorial/modules.html
la source
Supposons que vous ayez le code suivant dans un module appelé foo:
puis dans votre propre module vous avez:
Vous avez maintenant un module difficile à déboguer qui semble contenir l'etree de lxml, mais qui contient vraiment ElementTree à la place.
la source
Ce sont toutes de bonnes réponses. Je vais ajouter que lorsque vous apprenez à de nouvelles personnes à coder en Python, il
import *
est très difficile de gérer cela . Même si vous ou eux n'avez pas écrit le code, c'est toujours une pierre d'achoppement.J'apprends aux enfants (environ 8 ans) à programmer en Python pour manipuler Minecraft. J'aime leur donner un environnement de codage utile pour travailler avec ( Atom Editor ) et enseigner le développement piloté par REPL (via bpython ). Dans Atom, je trouve que les astuces / complétion fonctionnent aussi efficacement que bpython. Heureusement, contrairement à certains autres outils d'analyse statistique, Atom n'est pas dupe
import *
.Cependant, prenons cet exemple ... Dans ce wrapper, ils ont
from local_module import *
un tas de modules comprenant cette liste de blocs . Ignorons le risque de collisions d'espace de noms. Ce faisant,from mcpi.block import *
ils font de cette liste entière de types obscurs de blocs quelque chose que vous devez examiner pour savoir ce qui est disponible. S'ils avaient plutôt utiliséfrom mcpi import block
, vous pouvez taperwalls = block.
et une liste de saisie semi-automatique apparaîtra.la source
Compris les points valides que les gens mettent ici. Cependant, j'ai un argument selon lequel, parfois, "l'importation d'étoiles" n'est pas toujours une mauvaise pratique:
const.py
:import const
, alors pour chaque constante, je dois la désigner commeconst.SOMETHING
, ce 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 va à l'encontre du but de la structuration.from const import *
peut être un meilleur choix.la source
C'est une pratique très MAUVAISE pour deux raisons:
Pour le point 1 : Voyons un exemple de ceci:
Ici, en voyant le code ne sera obtenir une idée au sujet de quel module
b
,c
etd
appartient en réalité.D'un autre côté, si vous le faites comme:
C'est beaucoup plus propre pour vous, et la nouvelle personne qui rejoindra votre équipe aura une meilleure idée.
Pour le point 2 : disons les deux
module1
etmodule2
ayez la variable commeb
. Quand je fais:Ici, la valeur de
module1
est perdue. Il sera difficile de déboguer pourquoi le code ne fonctionne pas même s'ilb
est déclaré dansmodule1
et j'ai écrit le code en attendant que mon code soit utilisémodule1.b
Si vous avez les mêmes variables dans différents modules et que vous ne souhaitez pas importer le module entier, vous pouvez même faire:
la source
En guise de test, j'ai créé un module test.py avec 2 fonctions A et B, qui impriment respectivement "A 1" et "B 1". Après avoir importé test.py avec:
. . . Je peux exécuter les 2 fonctions comme test.A () et test.B (), et "test" apparaît comme un module dans l'espace de noms, donc si j'édite test.py je peux le recharger avec:
Mais si je fais ce qui suit:
il n'y a pas de référence à "test" dans l'espace de noms, il n'y a donc aucun moyen de le recharger après une édition (pour autant que je sache), ce qui est un problème dans une session interactive. Considérant que l'un des éléments suivants:
ajoutera "test" ou "tt" (respectivement) comme noms de module dans l'espace de noms, ce qui permettra le rechargement.
Si je fais:
les noms «A» et «B» apparaissent dans l'espace de noms en tant que fonctions . Si j'édite test.py et que je répète la commande ci-dessus, les versions modifiées des fonctions ne sont pas rechargées.
Et la commande suivante provoque un message d'erreur.
Si quelqu'un sait comment recharger un module chargé avec "from module import *", veuillez poster. Sinon, ce serait une autre raison d'éviter le formulaire:
la source
Comme suggéré dans la documentation, vous ne devriez (presque) jamais utiliser
import *
dans le code de production.Alors que l'importation à
*
partir d'un module est mauvaise, l' importation * à partir d'un package est encore pire. Par défaut,from package import *
importe tous les noms définis par le package__init__.py
, y compris tous les sous-modules du package chargés par lesimport
instructions précédentes .Cependant, si le
__init__.py
code d' un package définit une liste nommée__all__
, elle est considérée comme la liste des noms de sous-modules qui doivent être importés en cas defrom package import *
rencontre.Considérez cet exemple (en supposant qu'il n'y a pas de
__all__
défini danssound/effects/__init__.py
):La dernière instruction importera les modules
echo
etsurround
dans l'espace de noms actuel (éventuellement en remplaçant les définitions précédentes) car ils sont définis dans lesound.effects
package lorsque l'import
instruction est exécutée.la source