Jai toujours utilisé cette méthode:

from sys import argv 

et utilisez argv avec seulement argv . Mais il existe une convention dutilisation de ceci:

import sys 

et dutiliser largv par sys.argv

La deuxième méthode rend le code auto-documenté et jy adhère (vraiment) . Mais la raison pour laquelle je préfère la première méthode est quelle est rapide parce que nous importons uniquement la fonction nécessaire plutôt que dimporter le module entier (qui contient plus de fonctions inutiles que python perdra du temps à les importer). Notez que je nai besoin que de argv et que toutes les autres fonctions de sys me sont inutiles.

Donc, mes questions le sont. La première méthode rend-elle vraiment le script rapide? Quelle méthode est la plus préférée? Pourquoi?

Commentaires

Réponse

Limportation du module ne gaspille rien ; le module est toujours entièrement importé (dans le mappage sys.modules), donc que vous utilisiez import sys ou from sys import argv ne fait aucune chance.

La seule différence entre les deux instructions est le nom lié; import sys lie le nom sys au module (donc sys -> sys.modules["sys"]), tandis que from sys import argv se lie un nom différent, argv, pointant directement sur lattribut contenu à lintérieur du module (donc argv -> sys.modules["sys"].argv). Le reste de la Le module sys est toujours là, que vous utilisiez autre chose du module ou non.

Il ny a pas non plus de différence de performances entre les deux approches. Oui, sys.argv doit rechercher deux choses; il doit rechercher sys dans votre espace de noms global (trouve le module), puis rechercher lattribut argv. Et oui, en utilisant from sys import argv vous pouvez ignorer la recherche dattribut, puisque vous avez déjà une référence directe à lattribut. Mais linstruction import doit encore faire ce travail, elle recherche le même attribut lors de limportation, et vous naurez plus quà utiliser argv une fois . Si vous deviez utiliser argv des milliers de fois dans une boucle, cela pourrait peut-être faire une différence, mais dans ce cas précis, ce nest vraiment pas le cas .

Le choix entre lun ou lautre devrait donc être basé sur le style de codage .

Dans un module large , Jutiliserais certainement import sys; la documentation du code est importante, et lutilisation de sys.argv quelque part dans un gros module rend bien plus clair ce à quoi vous faites référence que ce que argv ne le ferait jamais.

Si le seul endroit où vous utilisez argv est dans un bloc "__main__" pour appeler un main(), utilisez certainement from sys import argv si vous vous sentez plus heureux à ce sujet:

if __name__ == "__main__": from sys import argv main(argv) 

I « Jutilise encore import sys moi-même. Toutes choses étant égales par ailleurs (et elles sont, exactement, en termes de performances et nombre de caractères utilisés pour lécrire) , cest juste plus facile à regarder pour moi.

Si vous importez quelque chose autre , alors peut-être que les performances entrent en jeu. Mais seulement si vous utilisez un nom spécifique dans un module plusieurs fois , dans une boucle critique par exemple. Mais ensuite, créer un nom local (dans une fonction) sera encore plus rapide:

 import somemodule def somefunction(): localname = somemodule.somefunctionorother while test: # huge, critical loop foo = localname(bar) 

Commentaires

  • Il y a aussi la situation où vous avez un package avec des sous-packages ou des modules qui expose un attribut de lun de ces sous-packages / modules dans le package de niveau supérieur. Lutilisation de from...import vous permet de faire package.attribute plutôt que package.subpackage_or_module.attribute, ce qui peut être utile si vous ont des regroupements logiques ou conceptuels dans le package mais que vous souhaitez rendre les choses un peu plus pratiques pour les utilisateurs de votre package. (numpy fait quelque chose comme ça, je crois.)
  • Dans django, vous avez des tonnes dendroits où des choses comme from django.core.management.base import BaseCommand sont meilleurs, et toute autre chose (en particulier import django) conduirait à un code illisible. Donc, même si jaime cette réponse, je pense quil y a des bibliothèques (et surtout des frameworks) dans lesquelles la convention est de violer limportation nue.Comme toujours, utilisez votre jugement sur ce qui est le mieux dans une situation donnée. Mais err du côté de lexplicite (en dautres termes, je suis daccord pour la plupart).
  • @JAB: vous pouvez toujours utiliser import ... as pour trouver le package à un autre nom: import package.subpackage_or_module as shortname. from parent import sub fait essentiellement la même chose.
  • so wether you use import sys or from sys import argv makes no odds cela ne semble pas être le cas avec IDLE. le simple fait dimporter le module nimporte pas ses fonctions et je ne peux lappeler dans le shell IDLE que par < module >. < function > nom
  • @Suncatcher: lisez ma réponse en entier. La phrase que vous citez parle de la quantité importée et non du nom lié. Ce ‘ est traité ailleurs dans la réponse.

Réponse

Il y a deux raisons en faveur dutiliser import module plutôt que from module import function.

Le premier est lespace de noms. Limportation dune fonction dans lespace de noms global risque de provoquer des collisions de noms.

Le second nest pas pertinent pour les modules standard, mais significatif pour vos propres modules, en particulier pendant le développement. Cest loption de reload() un module. Considérez ceci:

from module import func ... reload(module) # func still points to the old code 

Dun autre côté

import module ... reload(module) # module.func points to the new code 

Quant à la vitesse .. .

nous importons uniquement la fonction nécessaire plutôt que dimporter tout le module (qui contient plus de fonctions inutiles que python perdra du temps à les importer)

Que vous importiez un module ou importiez une fonction depuis un module, Python analysera tout le module. Dans les deux cas, le module est importé. « Importer une fonction » nest rien de plus que de lier la fonction à un nom. En fait, import module est moins de travail pour linterprète que from module import func.

Commentaires

  • reload () était intégré à Python 2; Ce nest plus le cas pour Python 3.
  • Je pensais quil y avait aussi des implications à voir avec les dépendances dimportation circulaire?

Réponse

Jutilise des from import chaque fois que cela améliore la lisibilité. Par exemple, je préfère (les points-virgules ne servent quà économiser de lespace ici):

from collections import defaultdict from foomodule import FooBar, FooBaz from twisted.internet.protocol import Factory defaultdict(); FooBar(); FooBaz(); Factory() 

au lieu de:

import collections import foomodule import twisted.internet.protocol collections.defaultdict(); foomodule.FooBar(); foomodule.FooBaz() twisted.internet.protocol.Factory() 

Ce dernier est plus difficile à lire (et à écrire) pour moi car il contient tellement dinformations redondantes. En outre, il est utile de savoir à l’avance quelles parties d’un module j’utilise.

Je préfère les import réguliers si j’utilise beaucoup des noms courts dun module:

import sys sys.argv; sys.stderr; sys.exit() 

Ou si un nom est si générique quil na pas de sens en dehors de son espace de noms:

import json json.loads(foo) from json import loads loads(foo) # potentially confusing 

Commentaires

  • Cest ma réponse préférée. ‘ Lexplicite vaut mieux que limplicite ‘ entre parfois en conflit avec la lisibilité, la simplicité et le DRY. Surtout lorsque vous utilisez un framework comme Django.

Réponse

À mon avis, en utilisant import améliore la lisibilité. Lors de la révision du code Python, jaime voir doù vient la fonction ou la classe donnée là où elle est utilisée. Cela mévite de faire défiler vers le haut du module pour obtenir ces informations.

En ce qui concerne les noms de modules longs, jutilise simplement le mot-clé as et je leur donne des raccourcis alias:

import collections as col import foomodule as foo import twisted.internet.protocol as twip my_dict = col.defaultdict() foo.FooBar() twip_fac = twip.Factory() 

À titre dexception, jutilise toujours la notation from module import something lorsque je traite le __future__. Vous ne pouvez « pas faire autrement quand vous voulez que toutes les chaînes soient unicode par défaut dans Python 2, par exemple

from __future__ import unicode_literals from __future__ import print_function 

Commentaires

  • Amen!  » importer comme  » est une combinaison gagnante 🙂

Réponse

Bien que import sys et from sys import agrv tous deux importent lintégralité du module sys, ce dernier utilise la liaison de nom de sorte que seul le module argv est accessible au reste du code.

Pour certaines personnes, ce style serait préféré car il ne rend accessible que la fonction que vous avez explicitement indiquée.

Cela introduit cependant des conflits de nom potentiels. Et si vous aviez un autre module nommé argv? Notez que vous pouvez également importer explicitement la fonction et la renommer avec from sys import argv as sys_argv, une convention qui répond à limportation explicite et est moins susceptible de donner un espace de nom collisions.

Commentaires

  • Comment est-ce que if sys_argv: est meilleur que if sys.argv:? Je sais ce que signifie la deuxième déclaration, je nai aucune idée de ce que signifie la première forme sans revenir à limport bizarre.

Réponse

Je me suis récemment posé cette question. Jai chronométré les différentes méthodes.

bibliothèque de requêtes

def r(): import requests return "hello" timeit r() # output: 1000000 loops, best of 3: 1.55 µs per loop def rg(): from requests import get return "hello" timeit rg() # output: 100000 loops, best of 3: 2.53 µs per loop 

bibliothèque beautifulsoup

def bs(): import bs4 return "hello" timeit bs() # output: 1000000 loops, best of 3: 1.53 µs per loop def be(): from bs4 import BeautifulSoup return "hello" timeit be() # output: 100000 loops, best of 3: 2.59 µs per loop 

bibliothèque json

def js(): import json return "hello" timeit js() # output: 1000000 loops, best of 3: 1.53 µs per loop def jl(): from json import loads return "hello" timeit jl() # output: 100000 loops, best of 3: 2.56 µs per loop 

bibliothèque sys

def s(): import sys return "hello" timeit s() # output: 1000000 loops, best of 3: 1.55 µs per loop def ar(): from sys import argv return "hello" timeit ar() # output: 100000 loops, best of 3: 2.87 µs per loop 

Il semble moi, il y a une légère différence de performances.

Commentaires

  • Vous ajoutez une recherche dattribut. Pour comparer correctement import module avec from module import name, ajoutez cette recherche de nom à import module cas. Par exemple. ajoutez la ligne sys.argv au test ar, etc. Il y aura toujours une différence, car le travail effectué est légèrement différent, car un code doctet différent est généré et différents chemins de code sont exécutés.
  • Notez que jaborde directement cette différence dans ma réponse; il y aura une différence entre utiliser import sys et utiliser sys.argv des milliers de fois dans une boucle et from sys import argv puis en utilisant simplement argv. Mais vous ne ‘ t. Pour les choses que vous ne faites quune fois au niveau global de votre module, vous devriez vraiment optimiser la lisibilité, pas les différences microscopiques de minutage.
  • Ahhhh! Et je pensais que jétais sur quelque chose! 🙂 Jai seulement écrémé votre réponse. On dirait que jai sauté le pistolet sur celui-là. Ça fait du bien dêtre humilié.

Réponse

En regardant les fragments de code publiés, en important des modules entiers et en faisant référence à module.function est à peu près la norme, du moins pour les modules standard. La seule exception semble être datetime

from datetime import datetime, timedelta 

donc vous pouvez dire datetime.now() plutôt que datetime.datetime.now().

Si vous êtes préoccupé par les performances, vous pouvez toujours dire (par exemple)

argv = sys.argv 

puis faites votre code critique de performance puisque la recherche du module est déjà faite. Cependant, bien que cela fonctionne avec les fonctions / méthodes, la plupart des IDE seront confus et nauront pas (par exemple) afficher un lien / une signature source pour la fonction quand elle est assignée à une variable.

Réponse

Je veux juste ajouter que si vous faites quelque chose comme

from math import sin 

(ou toute autre bibliothèque intégrée comme sys ou posix), alors sin être inclus dans la documentation de votre module (cest-à-dire lorsque vous faites >>> help(mymodule) ou $ pydoc3 mymodule. Pour éviter cela, importez en utilisant:

import math from math import sin as _sin 

PS: une bibliothèque intégrée est celle qui est compilée à partir du code C et incluse avec Python. argparse, os et io ne sont pas des packages intégrés

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *