Ik heb altijd deze methode gebruikt:

from sys import argv 

en gebruik argv met slechts argv . Maar er is een conventie om dit te gebruiken:

import sys 

en het gebruik van argv door sys.argv

De tweede methode zorgt ervoor dat de code zelf gedocumenteerd is en ik (echt) houd me eraan. Maar de reden dat ik de voorkeur geef aan de eerste methode is dat deze snel is omdat we alleen de functie importeren die nodig is in plaats van de hele module te importeren (die meer nutteloze functies bevat die Python tijd zal verspillen met het importeren ervan). Merk op dat ik alleen argv nodig heb en alle andere functies van sys zijn nutteloos voor mij.

Dus mijn vragen zijn. Maakt de eerste methode het script echt snel? Welke methode heeft de meeste voorkeur? Waarom?

Reacties

Answer

Het importeren van de module “verspilt niets ; de module is altijd volledig geïmporteerd (in de sys.modules mapping), dus of je nu import sys of from sys import argv maakt geen enkele kans.

Het enige verschil tussen de twee uitspraken is welke naam gebonden is; import sys bindt de naam sys naar de module (dus sys -> sys.modules["sys"]), terwijl from sys import argv bindt een andere naam, argv, die rechtstreeks naar het kenmerk in de module wijst (dus argv -> sys.modules["sys"].argv). De rest van th De sys module is er nog, of je nu iets anders uit de module gebruikt of niet.

Er is ook geen prestatieverschil tussen de twee benaderingen. Ja, sys.argv moet twee dingen opzoeken; het moet sys opzoeken in je globale naamruimte (vindt de module), en dan het attribuut argv opzoeken. En ja, door from sys import argv te gebruiken, kunt u het opzoeken van het attribuut overslaan, aangezien u al een directe verwijzing naar het attribuut heeft. Maar de import -instructie moet dat werk nog steeds doen, het zoekt hetzelfde attribuut op bij het importeren, en je “zult alleen argv een keer . Als je argv duizenden keren in een lus zou moeten gebruiken, zou het misschien een verschil kunnen maken, maar in dit specifieke geval doet het echt niet .

De keuze tussen de een of de ander moet in plaats daarvan gebaseerd zijn op coderingsstijl .

In een grote module , Ik “zou zeker import sys gebruiken; codedocumentatie is van belang, en als je sys.argv ergens in een grote module gebruikt, wordt het veel duidelijker waarnaar je verwijst dan alleen argv ooit zou doen.

Als de enige plaats die u gebruikt argv zich in een "__main__" blok bevindt om een functie, gebruik in elk geval from sys import argv als je je daar gelukkiger bij voelt:

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

I “d gebruik nog steeds import sys daar zelf. Alle dingen zijn gelijk (en ze zijn, precies, in termen van prestaties en aantal tekens gebruikt om het te schrijven) , dat is gewoon makkelijker voor het oog voor mij.

Als u iets anders helemaal importeert, komt de uitvoering misschien in het spel. Maar alleen als u een specifieke naam in een module vele malen , in een kritieke lus bijvoorbeeld. Maar dan gaat het maken van een lokale naam (binnen een functie) nog sneller:

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

Opmerkingen

  • Er is ook de situatie dat je een pakket hebt met subpakketten of modules die een attribuut van een van die subpakketten / modules in het pakket op het hoogste niveau blootlegt. Door from...import te gebruiken, kun je package.attribute doen in plaats van package.subpackage_or_module.attribute, wat handig kan zijn als je hebben logische of conceptuele groeperingen binnen het pakket, maar willen de zaken een beetje handiger maken voor gebruikers van uw pakket. (numpy doet zoiets, geloof ik.)
  • In django heb je talloze plekken waar dingen als from django.core.management.base import BaseCommand zijn beter, en al het andere (vooral import django) zou tot onleesbare code leiden. Dus hoewel ik dit antwoord leuk vind, denk ik dat er enkele bibliotheken zijn (en vooral enkele frameworks) waarin de conventie is om de kale import te schenden.Gebruik zoals altijd uw oordeel over wat het beste is in een bepaalde situatie. Maar vergis je aan de kant van expliciet (met andere woorden, ik ben het grotendeels eens).
  • @JAB: je kunt nog steeds import ... as gebruiken om het pakket te vinden een andere naam: import package.subpackage_or_module as shortname. from parent import sub doet in wezen hetzelfde.
  • so wether you use import sys or from sys import argv makes no odds dit lijkt niet het geval te zijn met IDLE. alleen het importeren van de module importeert zijn functies niet en ik kan het alleen in IDLE-shell aanroepen met < module >. < functie > naam
  • @Suncatcher: lees mijn antwoord volledig. De zin die u citeert, vertelt hoeveel er wordt geïmporteerd, niet welke naam is gebonden. Dat ‘ wordt elders in het antwoord behandeld.

Antwoord

Er zijn twee redenen om import module te gebruiken in plaats van from module import function.

De eerste is de naamruimte. Het importeren van een functie in de globale naamruimte riskeert naambotsingen.

Ten tweede is “niet zo relevant voor standaardmodules, maar significant voor uw eigen modules, vooral tijdens de ontwikkeling. Het is de optie om reload() een module. Overweeg dit:

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

Anderzijds

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

Wat betreft snelheid .. .

we importeren alleen de functie die nodig is in plaats van de hele module te importeren (die meer nutteloze functies bevat die Python tijd zal verspillen met het importeren ervan)

Of je nu een module importeert of een functie uit een module importeert, Python zal de hele module ontleden. Hoe dan ook, de module wordt geïmporteerd. “Een functie importeren” is niets meer dan de functie aan een naam binden. In feite is import module minder werk voor een tolk dan from module import func.

Opmerkingen

  • reload () was ingebouwd in Python 2; dat is niet langer het geval voor Python 3.
  • Ik dacht dat er ook implicaties waren die te maken hadden met afhankelijkheden van circulaire import?

Antwoord

Ik gebruik from import s wanneer het de leesbaarheid verbetert. Ik geef bijvoorbeeld de voorkeur aan (puntkommas zijn hier alleen om ruimte te besparen):

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

in plaats van:

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

Dit laatste is voor mij moeilijker te lezen (en te schrijven) omdat het zoveel overtollige informatie bevat. Het is ook handig om van tevoren te weten welke delen van een module ik “gebruik.

Ik geef de voorkeur aan gewone import s als ik veel gebruik van korte namen uit een module:

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

Of als een naam zo algemeen is dat hij “buiten de naamruimte” geen betekenis heeft:

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

Reacties

  • Dit is mijn favoriete antwoord. ‘ Expliciet is beter dan impliciet ‘ conflicteert soms met leesbaarheid, eenvoud en DROOG. Vooral als je een framework zoals Django gebruikt.

Answer

Naar mijn mening gebruik ik gewoon import verbetert de leesbaarheid. Bij het bekijken van Python-code vind ik het leuk om te zien waar de gegeven functie of klasse vandaan komt, precies waar deze wordt gebruikt. Het bespaart me om naar de bovenkant van de module te scrollen om die info te krijgen.

Wat betreft de lange modulenamen gebruik ik gewoon het as trefwoord en geef ze kort aliassen:

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

Als uitzondering gebruik ik altijd de from module import something -notatie wanneer ik te maken heb met de __future__ module. Je kunt het gewoon “niet op een andere manier doen als je wilt dat alle strings standaard unicode zijn in Python 2, bijv.

from __future__ import unicode_literals from __future__ import print_function 

Reacties

  • Amen! ” importeren als ” is een winnende combinatie 🙂

Antwoord

Hoewel import sys en from sys import agrv beide importeren de volledige sys module, de laatste gebruikt name binding dus alleen de argv module is toegankelijk voor de rest van de code.

Voor sommige mensen zou dit de voorkeursstijl zijn, aangezien het alleen de functie toegankelijk maakt die je expliciet vermeldt.

Het introduceert echter mogelijke naamconflicten. Wat als je een andere module had met de naam argv? Let op: u kunt de functie ook expliciet importeren en hernoemen met from sys import argv as sys_argv, een conventie die voldoet aan de expliciete import en het is minder waarschijnlijk dat u naamruimte geeft botsingen.

Reacties

  • Dus hoe is if sys_argv: beter dan if sys.argv:? Ik weet wat de tweede verklaring betekent, ik heb geen idee wat de eerste vorm betekent zonder terug te gaan naar de bizarre betekenis.

Antwoord

Ik heb deze vraag onlangs aan mezelf gesteld. Ik heb de verschillende methoden getimed.

vraagt bibliotheek

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 

beautifulsoup bibliotheek

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 

json-bibliotheek

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 

sys-bibliotheek

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 

Het lijkt erop dat mij dat er een klein verschil in prestatie is.

Opmerkingen

  • U voegt een attribuutzoekopdracht toe. Om import module te vergelijken met from module import name, voegt die naamzoekopdracht toe aan de import module geval. Bijv. voeg de regel sys.argv toe aan de ar -test, enz. Er zal nog steeds een verschil zijn, omdat het verrichte werk enigszins anders, aangezien er verschillende bytecodes worden gegenereerd en verschillende codepaden worden uitgevoerd.
  • Merk op dat ik dat verschil direct in mijn antwoord behandel; er zal een verschil zijn tussen import sys en sys.argv duizenden keren in een lus gebruiken versus from sys import argv gebruik dan alleen argv. Maar je doet ‘ t. Voor dingen die je slechts een keer doet op het globale niveau van je module, zou je echt moeten optimaliseren voor leesbaarheid, niet voor microscopische verschillen in timing.
  • Ahhhh! En ik dacht dat ik iets van plan was! 🙂 Ik heb alleen je antwoord afgetapt. Het lijkt erop dat ik daar met het pistool op heb gesprongen. Het voelt goed om vernederd te worden.

Answer

Gepubliceerde codefragmenten bekijken, hele modules importeren en verwijzen naar module.function is vrijwel de standaard, althans voor standaardmodules. De enige uitzondering lijkt datetime

from datetime import datetime, timedelta 

te zijn, dus je kunt datetime.now()

.

Als u zich zorgen maakt over de prestaties, kunt u altijd zeggen (bijvoorbeeld)

argv = sys.argv 

en voer vervolgens uw prestatie-kritieke code uit aangezien het opzoeken van de module al is voltooid. Hoewel dit zal werken met functies / methoden, zullen de meeste IDEs in de war raken en (bijvoorbeeld) geen bronlink / handtekening voor de functie weergeven wanneer deze aan een variabele is toegewezen.

Antwoord

Ik wil dat gewoon toevoegen als je zoiets doet

from math import sin 

(of een andere ingebouwde bibliotheek zoals sys of posix), dan zal sin worden opgenomen in de documentatie voor uw module (dwz wanneer u >>> help(mymodule) of $ pydoc3 mymodule doet. Om dit te voorkomen, importeert u met:

import math from math import sin as _sin 

PS: een ingebouwde bibliotheek is een bibliotheek die is gecompileerd uit C-code en wordt meegeleverd met Python. argparse, os en io zijn geen ingebouwde pakketten

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *