Jeg har alltid brukt denne metoden:

from sys import argv 

og bruk argv med bare argv . Men det er en konvensjon å bruke dette:

import sys 

og bruke argv av sys.argv

Den andre metoden gjør koden selvdokumentert og jeg (virkelig) følger den. Men grunnen til at jeg foretrekker den første metoden er at den er rask fordi vi bare importerer funksjonen som trengs i stedet for å importere hele modulen (som inneholder flere ubrukelige funksjoner som python vil kaste bort tid på å importere dem). Merk at jeg bare trenger argv og alle andre funksjoner fra sys er ubrukelige for meg.

Så spørsmålene mine er. Gjør den første metoden virkelig skriptet raskt? Hvilken metode foretrekkes mest? Hvorfor?

Kommentarer

Svar

Import av modulen kaster ikke bort noe ; modulen er alltid fullstendig importert (til sys.modules kartleggingen), så uansett om du bruker import sys eller from sys import argv gir ingen odds.

Den eneste forskjellen mellom de to utsagnene er hva navnet er bundet; import sys binder navnet sys til modulen (så sys -> sys.modules["sys"]), mens from sys import argv binder et annet navn, argv, som peker rett på attributtet inne i modulen (så argv -> sys.modules["sys"].argv). Resten av th e sys -modulen er fremdeles der, enten du bruker noe annet fra modulen eller ikke.

Det er heller ingen ytelsesforskjell mellom de to tilnærmingene. Ja, sys.argv må slå opp to ting; det må slå opp sys i ditt globale navneområde (finner modulen), og slå opp attributtet argv. Og ja, ved å bruke from sys import argv kan du hoppe over attributtoppslaget, siden du allerede har en direkte referanse til attributtet. Men import utsagnet må fremdeles gjøre det arbeidet, det ser opp på samme attributt når du importerer, og du trenger bare å bruke argv en gang . Hvis du måtte bruke argv tusenvis av ganger i en løkke, kan det kanskje gjøre en forskjell, men i dette spesifikke tilfellet gjør det virkelig ikke .

Valget mellom den ene eller den andre da, bør være basert på kodestil i stedet.

I en stor modul , Jeg vil absolutt bruke import sys; kodedokumentasjon betyr noe, og bruk av sys.argv et eller annet sted i en stor modul gjør det mye klarere hva du refererer til enn bare argv noensinne ville gjort.

Hvis det eneste stedet du bruker argv er i en "__main__" -blokk for å ringe en main() -funksjon, bruk for all del from sys import argv hvis du føler deg lykkeligere med det:

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

I «d bruker fortsatt import sys der selv. Alt er likt (og de er, nøyaktig, når det gjelder ytelse og antall tegn som brukes til å skrive det) , det er bare lettere for øyet.

Hvis du importerer noe annet helt, så kan ytelse spille inn. Men bare hvis du bruker et bestemt navn i en modul mange ganger , for eksempel i en kritisk sløyfe. Men å lage et lokalt navn (i en funksjon) vil fortsatt være raskere:

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

Kommentarer

  • Det er også situasjonen der du har en pakke med underpakker eller moduler som avslører et attributt for en av disse underpakningene / modulene i toppnivåpakken. Ved å bruke from...import kan du gjøre package.attribute i stedet for package.subpackage_or_module.attribute, noe som kan være nyttig hvis du ha logiske eller konseptuelle grupperinger i pakken, men vil gjøre ting litt mer praktisk for brukere av pakken din. (numpy gjør noe slikt, tror jeg.)
  • I django har du mange flekker der ting som from django.core.management.base import BaseCommand er bedre, og alt annet (spesielt import django) vil føre til uleselig kode. Så mens jeg liker dette svaret, tror jeg det er noen biblioteker (og spesielt noen rammer) der konvensjonen skal bryte den nakne importen.Bruk som alltid din skjønn om hva som er best i en gitt situasjon. Men feil på siden av eksplisitt (med andre ord er jeg enig for det meste).
  • @JAB: du kan fortsatt bruke import ... as for å finne pakken til et annet navn: import package.subpackage_or_module as shortname. from parent import sub gjør i det vesentlige det samme.
  • so wether you use import sys or from sys import argv makes no odds dette ser ut til å ikke være tilfelle med IDLE. bare import av modulen importerer ikke funksjonene, og jeg kan bare kalle den i IDLE-skall ved å < modul >. < -funksjon > navn
  • @Suncatcher: les svaret mitt i sin helhet. Setningen du siterer snakker om hvor mye som importeres, ikke hvilket navn som er bundet. At ‘ er dekket andre steder i svaret.

Svar

Det er to grunner til å bruke import module i stedet for from module import function.

Først er navnområdet. Å importere en funksjon til det globale navneområdet risikerer navnekollisjoner.

Andre er ikke det som er relevant for standardmoduler, men viktig for deg som eier moduler, spesielt under utvikling. Det er alternativet å reload() en modul. Tenk på dette:

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

På den annen side

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

Når det gjelder hastighet .. .

vi importerer bare funksjonen som trengs i stedet for å importere hele modulen (som inneholder flere ubrukelige funksjoner som python vil kaste bort tid på å importere dem)

Enten du importerer en modul eller importerer en funksjon fra en modul, vil Python analysere hele modulen. Uansett importeres modulen. «Importere en funksjon» er ikke annet enn å binde funksjonen til et navn. Faktisk er import module mindre arbeid for tolk enn from module import func.

Kommentarer

  • reload () var en innebygd i Python 2; det er ikke lenger tilfelle for Python 3.
  • Jeg trodde det også var implikasjoner å gjøre med sirkulære importavhengigheter?

Svar

Jeg bruker from import s når det forbedrer lesbarheten. For eksempel foretrekker jeg (semikolon er bare for å spare plass her):

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

i stedet for:

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

Sistnevnte er vanskeligere å lese (og skrive) for meg fordi den inneholder så mye overflødig informasjon. Det er også nyttig å vite på forhånd hvilke deler av en modul jeg bruker.

Jeg foretrekker vanlige import s hvis jeg bruker mye med korte navn fra en modul:

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

Eller hvis et navn er så generisk at det ikke gir mening utenfor navnområdet:

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

Kommentarer

  • Dette er favorittsvaret mitt. ‘ Eksplisitt er bedre enn implisitt ‘ noen ganger i konflikt med lesbarhet, enkelhet og TØRR. Spesielt når du bruker et rammeverk som Django.

Svar

Etter min mening bruker jeg vanlig import forbedrer lesbarheten. Når jeg vurderer Python-kode, liker jeg å se hvor den gitte funksjonen eller klassen kommer fra akkurat der den brukes. Det sparer meg for å bla til toppen av modulen for å få den informasjonen.

Når det gjelder de lange modulnavnene, bruker jeg bare as søkeordet og gir dem korte aliaser:

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

Som unntak bruker jeg alltid from module import something -notasjonen når jeg håndterer __future__ -modul. Du kan bare ikke gjøre det på en annen måte når du vil at alle strengene skal være unicode som standard i Python 2, f.eks.

from __future__ import unicode_literals from __future__ import print_function 

Kommentarer

  • Amen! » importer som » er en vinnerkombinasjon 🙂

Svar

Selv om import sys og from sys import agrv begge importerer hele sys -modulen, sistnevnte bruker navnebinding slik at bare argv -modulen er tilgjengelig for resten av koden.

For noen mennesker vil dette være den foretrukne stilen, siden den bare gjør tilgjengelig den funksjonen du eksplisitt har oppgitt.

Det introduserer imidlertid potensielle navnekonflikter. Hva om du hadde en annen modul kalt argv? Merk at du også eksplisitt kan importere funksjonen og gi nytt navn med from sys import argv as sys_argv, en konvensjon som oppfyller den eksplisitte importen og som mindre sannsynlig gir navnet plass kollisjoner.

Kommentarer

  • Så hvordan er if sys_argv: noe bedre enn if sys.argv:? Jeg vet hva den andre uttalelsen betyr, jeg aner ikke hva den første formen betyr uten å gå tilbake til den bisarre importen.

Svar

Jeg spurte nylig dette spørsmålet til meg selv. Jeg tidsbestemte de forskjellige metodene.

forespørsler bibliotek

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 

vakker soppebibliotek

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-bibliotek

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-bibliotek

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 

Det ser ut til meg at det er en liten forskjell i ytelse.

Kommentarer

  • Du legger til i et attributtoppslag. For å sammenligne import module med from module import name riktig, legg til navnetoppslaget til import module sak. F.eks. legg til linjen sys.argv til ar -testen osv. Det vil fortsatt være en forskjell, fordi arbeidet som er utført er litt forskjellig, ettersom forskjellig bytekode genereres og forskjellige kodestier blir utført.
  • Merk at jeg adresserer den forskjellen direkte i svaret mitt; det vil være en forskjell mellom å bruke import sys og deretter bruke sys.argv tusenvis av ganger i en løkke vs. from sys import argv bruk deretter bare argv. Men du don ‘ t. For ting du bare gjør en gang på det globale nivået i modulen din, bør du virkelig optimalisere for lesbarhet, ikke mikroskopiske forskjeller i tidsinnstillinger.
  • Ahhhh! Og jeg trodde jeg var på vei til noe! 🙂 Jeg skummet bare svaret ditt. Det ser ut til at jeg hoppet pistolen på den. Føles bra å bli ydmyket.

Svar

Ser på publiserte kodefragmenter, importerer hele moduler og refererer til module.function er ganske mye standarden, i det minste for standardmoduler. Det ene unntaket ser ut til å være datetime

from datetime import datetime, timedelta 

slik at du kan si datetime.now() i stedet for datetime.datetime.now().

Hvis du er bekymret for ytelse, kan du alltid si (for eksempel)

argv = sys.argv 

og gjør deretter din ytelseskritiske kode siden moduloppslaget allerede er gjort. Men selv om dette vil fungere med funksjoner / metoder, vil de fleste IDEer bli forvirret og vil ikke (for eksempel) vise en kildekobling / signatur for funksjonen når den er tildelt en variabel.

Svar

Jeg vil bare legge til at hvis du gjør noe sånt som

from math import sin 

(eller et hvilket som helst annet innebygd bibliotek som sys eller posix), så vil sin inkluderes i dokumentasjonen for modulen din (dvs. når du gjør >>> help(mymodule) eller $ pydoc3 mymodule. For å unngå dette, importer ved å bruke:

import math from math import sin as _sin 

PS: et innebygd bibliotek er et som er samlet fra C-kode og følger med Python. argparse, os og io er ikke innebygde pakker

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *