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?
import *
ne fonctionne pas pour moi en premier lieu dans Python 2 ou 3.
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?
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.
numpy.any
observation any
quand ils le font from numpy import *
ou un outil «utile» le fait pour eux.
import *
rend l' ordre des import
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 vos import
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 vous
Selon le Zen de Python :
L'explicite vaut mieux que l'implicite.
... vous ne pouvez pas discuter avec ça, sûrement?
use strict
(JavaScript var
). 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.
import os, sys, foo, sqlalchemy, mystuff
from bar import *
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 de import *
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.
execfile()
**vars()
d'inclure des globaux si la fonction appelée est dans un autre fichier? : P
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:
def myFunc():
print 1
Dans votre code:
from foo import *
def doThis():
myFunc() # Which myFunc is called?
def myFunc():
print 2
http://docs.python.org/tutorial/modules.html
Notez qu'en général, la pratique d'importation à
*
partir d'un module ou d'un package est désapprouvée, car elle entraîne souvent un code mal lisible .
Supposons que vous ayez le code suivant dans un module appelé foo:
import ElementTree as etree
puis dans votre propre module vous avez:
from lxml import etree
from foo import *
Vous avez maintenant un module difficile à déboguer qui semble contenir l'etree de lxml, mais qui contient vraiment ElementTree à la place.
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 taper walls = block.
et une liste de saisie semi-automatique apparaîtra.
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 comme const.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.C'est une pratique très MAUVAISE pour deux raisons:
Pour le point 1 : Voyons un exemple de ceci:
from module1 import *
from module2 import *
from module3 import *
a = b + c - d
Ici, en voyant le code ne sera obtenir une idée au sujet de quel module b
, c
et d
appartient en réalité.
D'un autre côté, si vous le faites comme:
# 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
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
et module2
ayez la variable comme b
. Quand je fais:
from module1 import *
from module2 import *
print b # will print the value from module2
Ici, la valeur de module1
est perdue. Il sera difficile de déboguer pourquoi le code ne fonctionne pas même s'il b
est déclaré dans module1
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:
from module1 import b as mod1b
from module2 import b as mod2b
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:
import test
. . . 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:
import importlib
importlib.reload(test)
Mais si je fais ce qui suit:
from test import *
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:
import test
import test as tt
ajoutera "test" ou "tt" (respectivement) comme noms de module dans l'espace de noms, ce qui permettra le rechargement.
Si je fais:
from test import *
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.
importlib.reload(test) # Error - name 'test' is not defined
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:
from module import *
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 les import
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 de from package import *
rencontre.
Considérez cet exemple (en supposant qu'il n'y a pas de __all__
défini dans 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 *
La dernière instruction importera les modules echo
et surround
dans l'espace de noms actuel (éventuellement en remplaçant les définitions précédentes) car ils sont définis dans le sound.effects
package lorsque l' import
instruction est exécutée.