Olen aina käyttänyt tätä menetelmää:
from sys import argv
ja käytä argv
vain argv kanssa. Tämän käyttö on kuitenkin tapana:
import sys
ja argv: n käyttämisestä sys.argv
Toinen menetelmä tekee koodista itsedokumentoitavan ja pidän (todella) kiinni siitä. Mutta mieluummin ensimmäinen menetelmä on se, että se on nopea, koska tuomme vain tarvittavan toiminnon eikä koko moduulia (joka sisältää enemmän hyödyttömiä toimintoja, jotka python tuhlaa aikaa niiden tuomiseen). Huomaa, että tarvitsen vain argv: n ja kaikki muut sys: n toiminnot ovat minulle hyödyttömiä.
Joten kysymykseni ovat. Tekeekö ensimmäinen menetelmä todella käsikirjoituksen nopeasti? Mikä menetelmä on suosituin? Miksi?
Kommentit
vastaus
Moduulin tuominen ei tuhlaa mitään ; moduuli on aina täysin tuotu (sys.modules
-kartoitukseen), joten käytä import sys
tai from sys import argv
ei tee kertoimia.
Ainoa ero näiden kahden lauseen välillä on se, mikä nimi on sidottu; import sys
sitoo nimen sys
moduuliin (joten sys
-> sys.modules["sys"]
), kun taas from sys import argv
sitoutuu eri nimi, argv
, joka osoittaa suoraan moduulin sisällä olevaan määritteeseen (joten argv
-> sys.modules["sys"].argv
). Loput e sys
-moduuli on edelleen olemassa riippumatta siitä, käytätkö muuta moduulista vai ei.
Näiden kahden lähestymistavan välillä ei myöskään ole eroa. Kyllä, sys.argv
on etsittävä kahta asiaa; sen on etsittävä sys
maailmanlaajuisesta nimitilastasi (etsi moduulin) ja sitten määritteen argv
. Ja kyllä, käyttämällä from sys import argv
-ohjelmaa voit ohittaa määritteen haun, koska sinulla on jo suora viittaus määritteeseen. Mutta import
-lausekkeen on silti tehtävä tämä työ, se etsii samaa määritettä tuotaessa, ja sinun tarvitsee vain käyttää argv
kerran . Jos joudut käyttämään argv
tuhansia kertoja silmukassa, se voisi ehkä vaikuttaa, mutta tässä erityisessä tapauksessa se ei todellakaan ole .
Tällöin valinnan tulisi perustua koodaustyyliin .
isossa moduulissa , Käytän varmasti import sys
; koodidokumentaatiolla on merkitystä, ja sys.argv
-toiminnon käyttäminen jonnekin isossa moduulissa tekee paljon selvemmäksi, mihin tarkoitat kuin vain argv
koskaan.
Jos ainoa paikka, jota käytät argv
, on "__main__"
-lohkossa soittaaksesi main()
-funktiota, käytä kaikin keinoin from sys import argv
, jos sinusta tuntuu onnellisemmalta:
if __name__ == "__main__": from sys import argv main(argv)
I ”d käytän silti siellä itse import sys
. Kaikki asiat ovat tasa-arvoisia (ja ne ovat täsmälleen suorituskyvyn suhteen ja merkkien lukumäärä, joita käytetään sen kirjoittamiseen) , se on minulle vain helpompaa silmissä.
Jos tuot jotain muuta kokonaan, ehkä suorituskyky tulee esiin. Mutta vain jos käytät tiettyä nimeä moduuli monta kertaa , esimerkiksi kriittisessä silmukassa. Mutta sitten paikallisen nimen luominen (funktion sisällä) on yhä nopeampaa:
import somemodule def somefunction(): localname = somemodule.somefunctionorother while test: # huge, critical loop foo = localname(bar)
Kommentit
- On myös tilanne, jossa sinulla on paketteja, joissa on alipaketteja tai moduuleja, jotka paljastavat yhden näistä alipaketeista / moduuleista ylemmän tason paketissa. Käyttämällä
from...import
voit tehdäpackage.attribute
eikäpackage.subpackage_or_module.attribute
, mikä voi olla hyödyllistä, jos sinulla on loogisia tai käsitteellisiä ryhmitelmiä paketissa, mutta haluat tehdä asiat hieman mukavammiksi pakettisi käyttäjille. (numpy
tekee jotain tällaista, uskon.) - Djangossa sinulla on paljon paikkoja, joissa esimerkiksi
from django.core.management.base import BaseCommand
ovat parempia, ja mikä tahansa muu (etenkinimport django
) johtaisi lukukoodiin. Joten vaikka pidän tästä vastauksesta, mielestäni on joitain kirjastoja (ja erityisesti joitain kehyksiä), joissa yleissopimuksen on tarkoitus rikkoa paljasta tuontia.Kuten aina, käytä arviointiasi siitä, mikä on parasta tietyssä tilanteessa. Mutta erehdy eksplisiittisen suhteen (toisin sanoen olen samaa mieltä suurimmaksi osaksi). - @JAB: voit silti käyttää pakettia
import ... as
eri nimi:import package.subpackage_or_module as shortname
.from parent import sub
tekee olennaisesti saman. -
so wether you use import sys or from sys import argv makes no odds
näyttää siltä, ettei IDLE: ssä ole kyse. Pelkkä moduulin tuominen ei tuo sen toimintoja, ja voin kutsua sitä IDLE-kuoressa vain < -moduulilla >. < function > nimi - @Suncatcher: lue vastaukseni kokonaan. Lainailmaasi lause puhuu siitä, kuinka paljon tuodaan, ei siitä, mikä nimi on sidottu. Se ’ on katettu muualla vastauksessa.
Vastaa
import module
-sivun from module import function
sijaan kannattaa käyttää kahta syytä.
Ensimmäinen on nimitila. Funktion tuominen globaaliin nimiavaruuteen vaarantaa nimien törmäykset.
Toinen ei ole merkityksellinen vakiomoduuleille, mutta merkittävä sinulle omistaa moduuleja, etenkin kehityksen aikana. Se on vaihtoehto reload()
moduuli. Harkitse tätä:
from module import func ... reload(module) # func still points to the old code
Toisaalta
import module ... reload(module) # module.func points to the new code
Mitä tulee nopeuteen .. .
tuomme vain tarvittavan toiminnon koko moduulin tuonnin sijaan (joka sisältää enemmän hyödyttömiä toimintoja, joiden python tuhlaa aikaa niiden tuomiseen)
Onko tuot moduulin vai funktion moduulista, Python jäsentää koko moduulin. Kummassakin tapauksessa moduuli tuodaan. ”Funktion tuominen” ei ole muuta kuin funktion sitominen nimeen. Itse asiassa import module
on vähemmän tulkkityötä kuin from module import func
.
Kommentit
- reload () oli sisäänrakennettu Python 2: ssa; näin ei ole enää Python 3: ssa.
- Luulin, että myös pyöreiden tuontiriippuvuuksien kanssa oli vaikutuksia?
Vastaa
Käytän from import
s aina, kun se parantaa luettavuutta. Esimerkiksi, pidän mieluummin (puolipisteillä vain säästetään tilaa tässä):
from collections import defaultdict from foomodule import FooBar, FooBaz from twisted.internet.protocol import Factory defaultdict(); FooBar(); FooBaz(); Factory()
eikä:
import collections import foomodule import twisted.internet.protocol collections.defaultdict(); foomodule.FooBar(); foomodule.FooBaz() twisted.internet.protocol.Factory()
Jälkimmäistä on minulle vaikeampaa lukea (ja kirjoittaa), koska se sisältää niin paljon turhaa tietoa. Lisäksi on hyödyllistä tietää etukäteen, mitä moduulin osia käytän.
Pidän parempana tavallisista import
s, jos käytän paljon lyhyitä nimiä moduulista:
import sys sys.argv; sys.stderr; sys.exit()
Tai jos nimi on niin yleinen, että sillä ei ole merkitystä nimiavaruutensa ulkopuolella:
import json json.loads(foo) from json import loads loads(foo) # potentially confusing
Kommentit
- Tämä on suosikkivastaukseni. ’ eksplisiittinen on parempi kuin implisiittinen. ’ on joskus ristiriidassa luettavuuden, yksinkertaisuuden ja kuivuuden kanssa. Varsinkin kun käytetään kehystä, kuten Django.
Vastaa
Mielestäni käyttämällä säännöllistä import
parantaa luettavuutta. Tarkastellessani Python-koodia haluan nähdä, mistä annettu funktio tai luokka on peräisin siitä, mihin sitä käytetään. Se säästää minua vierittämästä moduulin yläosaan saadakseni nämä tiedot.
Pitkien moduulien nimien osalta käytän vain avainsanaa as
ja annan heille lyhyen aliakset:
import collections as col import foomodule as foo import twisted.internet.protocol as twip my_dict = col.defaultdict() foo.FooBar() twip_fac = twip.Factory()
Poikkeuksena käytän aina merkintää from module import something
, kun käsittelen __future__
-moduuli. Et voi tehdä sitä toisella tavalla, kun haluat kaikkien merkkijonojen olevan oletusarvoisesti unicode Python 2: ssa, esim.
from __future__ import unicode_literals from __future__ import print_function
Kommentit
- Amen! ” tuonti nimellä ” on voittoyhdistelmä 🙂
Vastaa
Vaikka import sys
ja from sys import agrv
molemmat tuovat koko sys
-moduulin, jälkimmäinen käyttää nimisidontaa, joten vain koodin argv
moduuliin pääsee muulle koodille.
Joillekin ihmisille tämä olisi ensisijainen tyyli, koska se tekee vain nimenomaisesti ilmoittamasi toiminnon saataville.
Se kuitenkin aiheuttaa mahdollisia ristiriitoja. Entä jos sinulla olisi toinen moduuli nimeltä argv
? Huomaa, että voit myös tuoda nimenomaisesti funktion ja nimetä sen uudelleen nimellä from sys import argv as sys_argv
, käytäntö, joka täyttää nimenomaisen tuonnin ja on vähemmän todennäköistä, että hän antaa nimitilaa törmäykset.
Kommentit
- Joten miten
if sys_argv:
on parempi kuinif sys.argv:
? Tiedän mitä toinen lausunto tarkoittaa, minulla ei ole aavistustakaan mitä ensimmäinen muoto tarkoittaa ilman paluuta omituiseen tuontiin.
vastaus
Esitin äskettäin tämän kysymyksen itselleni. Ajoitin eri menetelmät.
pyytää kirjastoa
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-kirjasto
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-kirjasto
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-kirjasto
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
Näyttää siltä minulle, että suorituskyvyssä on pieni ero.
Kommentit
- Olet lisäämässä attribuuttihaun. Jos haluat verrata
import module
-palveluafrom module import name
-palveluun oikein, lisää kyseisen nimen haku hakemistoonimport module
tapaus. Esimerkiksi. lisää rivisys.argv
ar
-testiin jne. Tällöin ero on edelleen, koska tehty työ on hieman eri, koska syntyy erilainen tavukoodi ja suoritetaan erilaisia kooditietä. - Huomaa, että käsittelen tätä eroa suoraan vastauksessani;
import sys
-toiminnon ja sittensys.argv
-tuotteen käyttäminen silmukassa tuhansien aikojen välillä eroaa välilläfrom sys import argv
käyttämällä vainargv
. Mutta et ’ t. Asioita varten, joita teet vain kerran moduulin globaalilla tasolla, sinun pitäisi todella optimoida luettavuus, älä mikroskooppisia eroja ajoituksissa. - Ahhhh! Ja ajattelin olevani jossakin asiassa! 🙂 Minä vain löysin vastauksesi. Näyttää siltä, että hyppäsin aseen sen päälle. Tuntuu hyvältä nöyryytetyksi.
Vastaa
Julkaistun koodin fragmenttien tarkasteleminen, kokonaisten moduulien tuonti ja div id = ”d4f287ac19”>
on melko vakio, ainakin vakiomoduuleille. Ainoa poikkeus näyttää olevandatetime
from datetime import datetime, timedelta
joten voit sanoa datetime.now()
eikä datetime.datetime.now()
.
Jos olet huolissasi suorituskyvystä, voit aina sanoa (esimerkiksi)
argv = sys.argv
ja tee sitten suorituskyvyn kannalta kriittinen koodi, koska moduulin haku on jo tehty. Vaikka tämä toimii toimintojen / menetelmien kanssa, useimmat IDE: t sekoittuvat ja eivät (esimerkiksi) näytä funktion lähdelinkkiä / allekirjoitusta, kun se on määritetty muuttujalle.
Vastaa
Haluan vain lisätä, että jos teet jotain
from math import sin
(tai mikä tahansa muu sisäänrakennettu kirjasto, kuten sys
tai posix
), sitten sin
sisällytetään moduulin dokumentaatioon (ts. kun teet >>> help(mymodule)
tai $ pydoc3 mymodule
. Välttääksesi tämän, tuoda käyttämällä:
import math from math import sin as _sin
PS: sisäänrakennettu kirjasto on C-koodista koottu ja Pythonin mukana oleva kirjasto. argparse
, os
ja io
eivät ole sisäänrakennettuja paketteja
from … import …
-syntaksin taustalle Pythonissa