web-dev-qa-db-fra.com

Que signifie exactement "import *"?

En Python, que fait exactement import * importer? Importe-t-il __init__.py trouvé dans le dossier contenant?

Par exemple, est-il nécessaire de déclarer from project.model import __init__, ou est from project.model import * suffisant?

44
ensnare

L '"avantage" de from xyz import * par opposition à d'autres formes d'importation, c'est qu'il importe tout (enfin, presque ... [voir (a) ci-dessous] tout) du module désigné sous le module actuel. Cela permet d'utiliser les différents objets (variables, classes, méthodes ...) du module importé sans les préfixer avec le nom du module . Par exemple

>>> from math import *
>>>pi
3.141592653589793
>>>sin(pi/2)
>>>1.0

Cette pratique (d'importer * dans l'espace de noms courant) est cependant déconseillée car elle

  • offre la possibilité de collisions d'espace de noms (par exemple, si vous aviez un nom de variable pi avant l'importation)
  • peut être inefficace si le nombre d'objets importés est important
  • ne documente pas explicitement l'origine de la variable/méthode/classe (c'est bien d'avoir cette "auto-documentation" du programme pour une future visite dans le code)

En règle générale, nous limitons donc cette pratique d'importation * aux tests ad hoc et similaires. Comme l'a souligné @ Denilson-Sá-Maia, certaines bibliothèques telles que (par exemple pygame) ont un sous-module où toutes les constantes et fonctions les plus couramment utilisées sont définies et ces sous-modules sont effectivement conçus à importer avec import *. En dehors de ces sous-modules spéciaux, il est par ailleurs préférable de ...:

importe explicitement seulement quelques objets

>>>from math import pi
>>>pi
>>>3.141592653589793
>>> sin(pi/2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'sin' is not defined

ou importez le module sous son propre espace de noms (ou un alias de celui-ci, en particulier s'il s'agit d'un nom long et que le programme référence plusieurs fois ses objets)

  >>>import math
  >>>math.pi
  >>>3.141592653589793
  etc..


  >>>import math as m  #bad example math being so short and standard...
  >>>m.pi
  >>>3.141592653589793
  etc..

Voir la documentation Python sur ce sujet

(a) Plus précisément, ce qui est importé avec from xyz import *?
si le module xyz définit un __all__ variable, il importera tous les noms définis dans cette séquence, sinon il importera tous les noms, sauf ceux qui commencent par un trait de soulignement.

Remarque De nombreuses bibliothèques ont sous-modules. Par exemple, la bibliothèque standard urllib comprend des sous-modules comme urllib.request, urllib.errors, urllib.response etc. Un point commun de confusion est que

from urllib import *

importerait tous ces sous-modules. Ce n'est PAS le cas : il faut les importer explicitement séparément avec, disons, from urllib.request import * etc. Ce n'est d'ailleurs pas spécifique à import *, plain import n'importera pas non plus les sous-modules (mais bien sûr, le * qui est souvent un raccourci pour "tout" peut induire les gens en erreur en pensant que tous les sous-modules et tout le reste seraient importés).

51
mjv

Il importe (dans l'espace de noms actuel) tous les noms que le module (ou package) répertorie dans son __all__ attribute - manque un tel attribut, tous les noms qui ne commencent pas par _.

Il est principalement conçu comme un raccourci pratique à utiliser uniquement dans les sessions d'interpréteur interactif: comme d'autres réponses le suggèrent, ne pas l'utiliser dans un programme.

Ma recommandation, par Google Python , est de n'importer que modules, pas les classes ou fonctions (ou autres noms) des modules. Le strict respect de cette règle garantit la clarté et la précision, et évite les pièges subtils qui peuvent survenir lorsque vous importez des "éléments à partir d'un module".

L'importation d'un package (ou quoi que ce soit de l'intérieur) charge et exécute intrinsèquement le __init__.py - ce fichier définit le corps du paquet. Cependant, il ne lie pas le nom __init__ dans votre espace de noms actuel (dans ce sens, il n'importe pas ce nom).

12
Alex Martelli

Oui. Il importe tout (qui n'est pas une variable privée, c'est-à-dire: des variables dont les noms commencent par _ ou __), et vous devriez essayer de ne pas l'utiliser selon " Importer correctement les modules en Python " pour éviter de polluer l'espace de noms local.

C'est suffisant, mais généralement vous devez soit faire import project.model, qui importe déjà __init__.py, par " nderstanding python imports ", mais peut devenir trop verbeux si vous l'utilisez trop ou import project.model as pm ou import project.model as model pour enregistrer quelques touches plus tard lorsque vous l'utiliserez.

Suivez les conseils d'Alex dans " Qu'est-ce que" import * "importe exactement? "

4
Esteban Küber

Si project.model Est un package, le module référencé par import project.model Provient de .../project/model/__init__.py. from project.model import * Vide tout de l'espace de noms de __init__.py Dans le vôtre. Il ne fait rien automatiquement avec les autres modules du modèle. Le style préféré est que __init__.py Ne contienne rien.

Jamais jamais jamais jamais utiliser import *. Cela rend votre code illisible et incontrôlable.

3
Mike Graham

Voici une belle façon de voir quelle étoile/astérisque (*) a importé d'un module:

before = dir()
from math import *
after = dir()
print(set(after) - set(before))

retour:

{'modf', 'pow', 'erfc', 'copysign', 'sqrt', 'atan2', 'e', 'tanh', 'pi', 'factorial', 'cosh', 'expm1', 'cos', 'fmod', 'frexp', 'log', 'acosh', 'sinh', 'floor', 'isclose', 'lgamma', 'ceil', 'gcd', 'ldexp', 'hypot', 'radians', 'atan', 'isnan', 'atanh', 'before', 'isinf', 'fabs', 'isfinite', 'log10', 'nan', 'tau', 'acos', 'gamma', 'asin', 'log2', 'tan', 'degrees', 'asinh', 'erf', 'fsum', 'inf', 'exp', 'sin', 'trunc', 'log1p'}

Je travaillais avec mon propre module, j'importais tout explicitement mais la liste des choses à importer devenait trop longue. Donc, j'ai dû utiliser cette méthode pour obtenir une liste de ce que * avait importé.

2
cardamom

Si le module en question (project.model dans votre cas) a défini une liste de piqûres nommée __all__, puis chaque variable nommée dans cette liste est importée. S'il n'y a pas une telle variable, il importe tout.