web-dev-qa-db-fra.com

En Python, que se passe-t-il lorsque vous importez à l'intérieur d'une fonction?

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

Réimporte-t-il chaque fois que la fonction est exécutée, ou peut-être une seule fois au début, que la fonction soit exécutée ou non?

140
Tim McJilton

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

Non; ou plutôt, Python sont essentiellement mis en cache chaque fois qu'ils sont importés, donc importer une seconde (ou troisième, ou quatrième ...) fois ne les oblige pas à effectuer l'intégralité de l'importation processus à nouveau 1

Importe-t-il une fois au début que la fonction soit exécutée ou non?

Non, il n'est importé que si et quand la fonction est exécutée. 2 ,

En ce qui concerne les avantages: cela dépend, je suppose. Si vous ne pouvez exécuter qu'une fonction très rarement et que vous n'avez pas besoin du module importé ailleurs, il peut être avantageux de ne l'importer que dans cette fonction. Ou bien s'il y a un conflit de noms ou une autre raison pour laquelle vous ne voulez pas que le module ou les symboles du module soient disponibles partout , vous pouvez uniquement les importer. dans une fonction spécifique. (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 de module.

121
mipadi

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 un autre formulaire importable) est chargé et sys.modules['goo'] est défini sur l'objet module ainsi construit. Toute importation future au sein de la même exécution du programme (là encore, que ce soit à l'intérieur ou à l'extérieur d'une fonction), il suffit de regarder sys.modules['goo'] et liez-le au nom_base goo dans la portée appropriée. La recherche dict et la liaison de noms sont des opérations très rapides.

En supposant que le tout premier import soit totalement amorti par la suite du programme, avoir la "portée appropriée" au niveau du module signifie que chaque utilisation de goo.this, goo.that, etc, est deux recherches dictées: une pour goo et une pour le nom de l'attribut. Le fait d'être "niveau de fonction" paie un paramètre de variable locale supplémentaire par exécution de la fonction (même plus rapide que la partie consultation du dictionnaire!), Mais enregistre une recherche dictée (en l'échangant contre une recherche de variable locale extrêmement rapide) pour chaque goo.this _ (etc) accès, réduisant de moitié le temps que prennent ces recherches.

Nous parlons de quelques nanosecondes d'une manière ou d'une autre, ce n'est donc pas une optimisation valable. L’avantage potentiellement important d’avoir le import dans une fonction est que cette fonction peut ne pas être nécessaire du tout dans une exécution donnée du programme, par exemple, cette fonction traite des erreurs, des anomalies et des situations rares dans général; Si c'est le cas, toute exécution qui n'a pas besoin de la fonctionnalité n'effectue même pas l'importation (et c'est une économie de microsecondes, pas seulement de nanosecondes). Seules les exécutions nécessitant la fonctionnalité en paieront le prix (modeste mais mesurable).

Il s’agit toujours d’une optimisation qui ne vaut que dans des situations assez extrêmes, et j’envisagerais de nombreuses autres avant d’essayer de réduire de cette façon les microsecondes.

38
Alex Martelli

Il importe une fois lorsque la fonction s'exécute pour la première fois.

Avantages:

  • les importations liées à la fonction, ils sont utilisés dans
  • facile à déplacer les fonctions autour du paquet

Les inconvénients:

  • ne pouvait pas voir quels modules ce module pourrait dépendre
9
SilentGhost

L'importation à l'intérieur d'une fonction importera effectivement le module une fois .. lors de la première exécution de la fonction.

Il doit importer aussi rapidement si vous l'importez en haut ou lorsque la fonction est exécutée. Ce n’est généralement pas une bonne raison d’importer dans un fichier. Avantages? Elle ne sera pas importée si la fonction n’est pas appelée. C’est en fait une raison raisonnable si votre module exige seulement que l’utilisateur ait un certain module installé s’ils utilisent des fonctions spécifiques de votre vôtre ...

Si ce n’est pas la raison pour laquelle vous faites cela, c’est certainement une idée dégoûtante.

5
royal

Puis-je suggérer en général que, au lieu de demander, "Est-ce que X améliorera mes performances?" vous utilisez le profilage pour déterminer où se trouve votre programme en fait passez votre temps, puis appliquez les optimisations en fonction du lieu où vous obtiendrez le plus d'avantages?

Vous pouvez ensuite utiliser le profilage pour vous assurer que vos optimisations vous ont également été bénéfiques.

4
gomad

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ée très rarement et qui est la seule à nécessiter l'importation. On dirait plutôt tiré par les cheveux, bien que ...

2
Tim Pietzcker