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 fairepackage.attribute
plutôt quepackage.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 particulierimport 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 queif 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
avecfrom module import name
, ajoutez cette recherche de nom àimport module
cas. Par exemple. ajoutez la lignesys.argv
au testar
, 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 utilisersys.argv
des milliers de fois dans une boucle etfrom sys import argv
puis en utilisant simplementargv
. 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
from … import …
en Python