537 votes

Les déclarations d'importation doivent-elles toujours figurer au début d'un module ?

PEP 8 États :

Les importations sont toujours placées en haut du fichier, juste après les commentaires et les docstrings du module, et avant les globales et les constantes du module.

Cependant, si la classe/méthode/fonction que j'importe n'est utilisée que dans de rares cas, il est sûrement plus efficace d'effectuer l'importation lorsqu'elle est nécessaire ?

N'est-ce pas :

class SomeClass(object):

    def not_often_called(self)
        from datetime import datetime
        self.datetime = datetime.now()

plus efficace que ça ?

from datetime import datetime

class SomeClass(object):

    def not_often_called(self)
        self.datetime = datetime.now()

6voto

giltay Points 681

Voici un exemple où toutes les importations se trouvent tout en haut (c'est la seule fois où j'ai eu besoin de faire cela). Je veux être capable de terminer un sous-processus à la fois sur Un*x et Windows.

import os
# ...
try:
    kill = os.kill  # will raise AttributeError on Windows
    from signal import SIGTERM
    def terminate(process):
        kill(process.pid, SIGTERM)
except (AttributeError, ImportError):
    try:
        from win32api import TerminateProcess  # use win32api if available
        def terminate(process):
            TerminateProcess(int(process._handle), -1)
    except ImportError:
        def terminate(process):
            raise NotImplementedError  # define a dummy function

(A revoir : ce que John Millikin dit.)

6voto

Drew Stephens Points 4692

C'est comme beaucoup d'autres optimisations - vous sacrifiez un peu de lisibilité pour la vitesse. Comme John l'a mentionné, si vous avez fait vos devoirs de profilage et que vous avez trouvé que ce changement est suffisamment utile, il est possible de le faire. y vous avez besoin de la vitesse supplémentaire, alors allez-y. Il serait probablement bon de mettre une note avec toutes les autres importations :

from foo import bar
from baz import qux
# Note: datetime is imported in SomeClass below

5voto

Jeremy Brown Points 4950

L'initialisation du module ne se produit qu'une fois - lors de la première importation. Si le module en question fait partie de la bibliothèque standard, il est probable que vous l'importiez également d'autres modules dans votre programme. Pour un module aussi répandu que datetime, il est également probable qu'il dépende d'un grand nombre d'autres bibliothèques standard. L'instruction import ne coûterait alors pas grand-chose puisque l'initialisation du module aurait déjà eu lieu. Tout ce qu'elle fait à ce stade est de lier l'objet module existant à la portée locale.

Si l'on ajoute à cette information l'argument de la lisibilité, je dirais qu'il est préférable de placer la déclaration d'importation au niveau du module.

5voto

Caumons Points 1702

Juste pour compléter La réponse de Moe et la question originale :

Lorsque nous devons traiter des dépendances circulaires, nous pouvons faire quelques "trucs". En supposant que nous travaillons avec des modules a.py y b.py qui contiennent x() et b y() respectivement. Alors :

  1. Nous pouvons déplacer l'un des from imports au bas du module.
  2. Nous pouvons déplacer l'un des from imports à l'intérieur de la fonction ou de la méthode qui nécessite réellement l'importation (ce n'est pas toujours possible, car vous pouvez l'utiliser à plusieurs endroits).
  3. Nous pouvons changer l'un des deux from imports pour être une importation qui ressemble à : import a

Donc, pour conclure. Si vous n'êtes pas en train de gérer les dépendances circulaires et de faire une sorte d'astuce pour les éviter, alors il est préférable de mettre tous vos imports au début pour les raisons déjà expliquées dans d'autres réponses à cette question. Et s'il vous plaît, lorsque vous faites ces "astuces", ajoutez un commentaire, il est toujours le bienvenu ! :)

4voto

Paul Points 1537

En plus des excellentes réponses déjà données, il est bon de noter que le placement des importations n'est pas seulement une question de style. Parfois, un module a des dépendances implicites qui doivent être importées ou initialisées en premier, et une importation de haut niveau pourrait conduire à des violations de l'ordre d'exécution requis.

Ce problème se pose souvent dans l'API Python d'Apache Spark, où vous devez initialiser le SparkContext avant d'importer tout paquet ou module pyspark. Il est préférable de placer les importations pyspark dans une portée où la disponibilité du SparkContext est garantie.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X