En Python, ce qui se passe lorsque vous importez à l'intérieur d'une fonction? [dupliquer]

cette question a déjà une réponse ici:

Quels sont les avantages et les inconvénients d'importer un module Python et/ou une fonction à l'intérieur d'une fonction, en ce qui concerne l'efficacité de la vitesse et de la mémoire?

est-ce qu'il réimporte chaque fois que la fonction est exécutée, ou peut-être juste une fois au début si la fonction est exécutée ou non?

116
demandé sur Michael Currie 2010-06-22 20:24:43

6 réponses

est-ce qu'il réimporte chaque fois que la fonction est exécutée?

non; ou plutôt, les modules Python sont essentiellement mis en cache chaque fois qu'ils sont importés, donc l'importation d'une deuxième (ou troisième, ou quatrième... le temps ne les oblige pas à recommencer tout le processus d'importation.

importe-t-il une fois au début si la fonction est exécutée ou non?

Non, c'est seulement importé si et lorsque la fonction est exécutée.

quant aux prestations: cela dépend, je suppose. Si vous ne pouvez exécuter une fonction que très rarement et n'avez pas besoin du module importé ailleurs, il peut être bénéfique de ne l'importer que dans cette fonction. Ou s'il y a un conflit de nom ou une autre raison vous ne voulez pas le module ou les symboles du module disponible partout , vous pouvez seulement vouloir l'importer dans un spécifique fonction. (Bien sûr, il y a toujours from my_module import my_function as f pour ces cas.)

en pratique générale, ce n'est probablement pas si bénéfique. En fait, la plupart des guides de style Python encouragent les programmeurs à placer toutes les importations au début du fichier module.

99
répondu mipadi 2010-06-22 16:29:47

la toute première fois que vous import goo de n'importe où (à l'intérieur ou à l'extérieur d'une fonction), goo.py (ou autre forme importante) est chargé et sys.modules['goo'] est réglé à l'objet module ainsi construit. Toute importation future au sein du même cycle du programme (encore une fois, que ce soit à l'intérieur ou à l'extérieur d'une fonction) il suffit de chercher sys.modules['goo'] et de le lier au nom de code goo dans la portée appropriée. La recherche dict et la reliure de noms sont des opérations très rapides.

en supposant le tout premier import est totalement amorti sur l'exécution du programme de toute façon, ayant la" portée appropriée "au niveau du module signifie chaque utilisation de goo.this , goo.that , etc, est deux recherches dict -- un pour goo et un pour le nom d'attribut. Le fait de l'avoir comme "niveau de fonction" paie un paramètre supplémentaire de variable locale par exécution de la fonction (encore plus rapide que la partie de recherche du dictionnaire!) mais économise une recherche dict (en l'échangeant pour une recherche locale-variable, extrêmement rapide) pour chaque goo.this (etc) accès, essentiellement réduire de moitié le temps de telles recherches prennent.

nous parlons de quelques nanosecondes d'une façon ou d'une autre, donc c'est à peine une optimisation valable. Le seul avantage potentiellement important d'avoir le import dans une fonction est quand cette fonction peut bien ne pas être nécessaire du tout dans une course donnée du programme, par exemple, cette fonction traite des erreurs, des anomalies, et des situations rares en général; si c'est le cas, toute course qui ne besoin de la fonctionnalité ne sera pas à même de réaliser l'importation (et c'est une économie de microsecondes, et pas seulement nanosecondes), ne fonctionne que avez besoin de la fonctionnalité de payer le (modeste mais mesurable) des prix.

c'est toujours une optimisation qui ne vaut la peine que dans des situations assez extrêmes, et il y en a beaucoup d'autres que je voudrais considérer avant d'essayer d'extraire les microsecondes de cette façon.

34
répondu Alex Martelli 2010-06-22 16:36:27

il importe Une fois lorsque la fonction exécute pour la première fois.

Pour:

  • importations liées à la fonction dans laquelle elles sont utilisées
  • fonctions faciles à déplacer autour du paquet

Inconvénients:

  • impossible de voir sur quels modules ce module pourrait dépendre
9
répondu SilentGhost 2010-06-22 16:26:58

Importer à l'intérieur d'une fonction importera effectivement le module une fois.. la première fois que la fonction est exécutée.

il devrait importer aussi vite si vous l'importez au sommet, ou quand la fonction est exécutée. Ce n'est généralement pas une bonne raison pour importer dans une def. Pros? Il ne sera pas importé si la fonction n'est pas appelée.. Il s'agit en fait d'une raison raisonnable si votre module exige seulement que l'utilisateur ait un certain module installé s'ils utilisent des fonctions spécifiques de la vôtre...

si ce n'est pas la raison pour laquelle tu fais ça, c'est presque certainement une mauvaise idée.

5
répondu royal 2010-06-22 16:28:11

Pourrais-je suggérer en général qu'au lieu de demander, "Est-ce que X améliorera ma performance?"vous utilisez le profilage pour déterminer où votre programme est réellement passer son temps et ensuite appliquer des optimisations en fonction de l'endroit où vous obtiendrez le plus d'avantages?

et ensuite vous pouvez utiliser le profilage pour s'assurer que vos optimisations ont réellement bénéficié vous aussi.

3
répondu gomad 2010-06-22 18:48:25

il importe Une fois lorsque la fonction est appelée pour la première fois.

je pourrais imaginer le faire de cette façon si j'avais une fonction dans un module importé qui est utilisé très seldomly et est le seul nécessitant l'importation. Semble un peu tiré par les cheveux, si...

2
répondu Tim Pietzcker 2010-06-22 16:27:47