Am folosit întotdeauna această metodă:
from sys import argv
și utilizați argv
doar cu argv . Dar există o convenție de a folosi acest lucru:
import sys
și de a folosi argv de sys.argv
A doua metodă face ca codul să se autodocumenteze și eu (într-adevăr) îl respect. Dar motivul pentru care prefer prima metodă este că este rapid, deoarece importăm doar funcția care este necesară, mai degrabă decât să importăm întregul modul (care conține mai multe funcții inutile, care Python va pierde timpul importându-le). Rețineți că am nevoie doar de argv și toate celelalte funcții din sys sunt inutile pentru mine.
Deci întrebările mele sunt. Prima metodă face ca scriptul să fie rapid? Ce metodă este cea mai preferată? De ce?
Comentarii
Răspuns
Importarea modulului nu risipește nimic ; modulul este întotdeauna complet importat (în sys.modules
mapare), deci dacă utilizați import sys
sau from sys import argv
nu face cote.
Singura diferență dintre cele două afirmații este ce nume este legat; import sys
leagă numele sys
la modul (deci sys
-> sys.modules["sys"]
), în timp ce from sys import argv
leagă un nume diferit, argv
, îndreptat direct către atributul conținut în interiorul modulului (deci argv
-> sys.modules["sys"].argv
). Restul a Modulul e sys
este încă acolo, indiferent dacă utilizați sau nu altceva din modul.
De asemenea, nu există nicio diferență de performanță între cele două abordări. Da, sys.argv
trebuie să caute două lucruri; trebuie să caute sys
în spațiul de nume global (găsește modulul), apoi să caute atributul argv
. Și da, folosind from sys import argv
puteți sări peste căutarea atributelor, deoarece aveți deja o referință directă la atribut. Dar declarația import
trebuie încă să facă acea lucrare, caută același atribut când importați și va trebui să folosiți doar argv
o dată . Dacă ar trebui să utilizați argv
de mii de ori într-o buclă, s-ar putea să facă o diferență, dar în acest caz specific chiar nu .
Alegerea dintre unul sau altul atunci ar trebui să se bazeze pe stilul de codare .
Într-un modul mare , Aș folosi cu siguranță import sys
; documentarea codului contează și utilizarea sys.argv
undeva într-un modul mare face mult mai clar la ce vă referiți decât doar argv
ar face vreodată.
Dacă singurul loc pe care îl utilizați argv
se află într-un bloc "__main__"
pentru a apela un main()
funcție, folosiți from sys import argv
dacă vă simțiți mai fericit cu privire la asta:
if __name__ == "__main__": from sys import argv main(argv)
I „Aș folosi încă import sys
acolo. Toate lucrurile sunt egale (și sunt, exact, în ceea ce privește performanța și numărul de caractere utilizate pentru a-l scrie) , asta este mai ușor pentru mine.
Dacă importați cu totul altceva altceva , poate că performanța intră în joc. Dar numai dacă utilizați un anumit nume într-un modulul de multe ori , într-o buclă critică, de exemplu. Dar atunci crearea unui nume local (în cadrul unei funcții) va fi mai rapidă:
import somemodule def somefunction(): localname = somemodule.somefunctionorother while test: # huge, critical loop foo = localname(bar)
Comentarii
- Există, de asemenea, situația în care aveți un pachet cu subpachete sau module care expune un atribut al unuia dintre acele subpachete / module din pachetul de nivel superior. Utilizarea
from...import
vă permite să facețipackage.attribute
în loc depackage.subpackage_or_module.attribute
, care poate fi util dacă au grupări logice sau conceptuale în cadrul pachetului, dar doresc să facă lucrurile puțin mai convenabile pentru utilizatorii pachetului dvs. (numpy
face așa ceva, cred.) - În django aveți tone de locuri în care lucruri precum
from django.core.management.base import BaseCommand
sunt mai bune și orice altceva (în specialimport django
) ar duce la codul ilizibil. Deci, deși îmi place acest răspuns, cred că există unele biblioteci (și mai ales câteva cadre) în care convenția este de a încălca importul.Ca întotdeauna, folosiți-vă judecata cu privire la ceea ce este mai bine într-o situație dată. Dar greșește din partea explicită (cu alte cuvinte sunt de acord în cea mai mare parte). - @JAB: poți folosi în continuare
import ... as
pentru a găsi pachetul către care un nume diferit:import package.subpackage_or_module as shortname
.from parent import sub
face, în esență, același lucru. -
so wether you use import sys or from sys import argv makes no odds
acest lucru pare să nu fie cazul IDLE. doar importul modulului nu își importă funcțiile și îl pot apela în shell IDLE numai prin < modul >. < funcție > nume - @Suncatcher: citiți răspunsul meu integral. Propoziția pe care o citați vorbește despre cât este importat, nu despre ce nume este legat. Acele ‘ acoperite în altă parte în răspuns.
Răspuns
Există două motive în favoarea utilizării import module
în loc de from module import function
.
În primul rând este spațiul de nume. Importarea unei funcții în spațiul de nume global riscă coliziunile de nume.
În al doilea rând nu este „relevant pentru modulele standard, dar semnificativ pentru propriile module, mai ales în timpul dezvoltării. Este opțiunea reload()
un modul. Luați în considerare acest lucru:
from module import func ... reload(module) # func still points to the old code
Pe de altă parte
import module ... reload(module) # module.func points to the new code
În ceea ce privește viteza .. .
importăm doar funcția necesară, mai degrabă decât să importăm întregul modul (care conține mai multe funcții inutile, pe care Python le va pierde timpul importându-le)
Fie că importați un modul sau importați o funcție dintr-un modul, Python va analiza întregul modul. Oricum, modulul este importat. „Importarea unei funcții” nu este altceva decât legarea funcției la un nume. De fapt, import module
este mai puțin de lucru pentru interpret decât from module import func
.
Comentarii
- reload () a fost un program încorporat în Python 2; acesta nu mai este cazul pentru Python 3.
- Am crezut că există și implicații legate de dependențele de import circular?
Răspuns
Folosesc from import
s ori de câte ori îmbunătățește lizibilitatea. De exemplu, prefer (punctele și virgulele sunt doar pentru a economisi spațiu aici):
from collections import defaultdict from foomodule import FooBar, FooBaz from twisted.internet.protocol import Factory defaultdict(); FooBar(); FooBaz(); Factory()
în loc de:
import collections import foomodule import twisted.internet.protocol collections.defaultdict(); foomodule.FooBar(); foomodule.FooBaz() twisted.internet.protocol.Factory()
Acesta din urmă este mai greu de citit (și de scris) pentru mine, deoarece conține atât de multe informații redundante. De asemenea, este util să știu din timp ce părți ale unui modul folosesc.
Prefer import
obișnuite dacă folosesc loturi nume scurte dintr-un modul:
import sys sys.argv; sys.stderr; sys.exit()
Sau dacă un nume este atât de generic încât nu are sens în afara spațiului său de nume:
import json json.loads(foo) from json import loads loads(foo) # potentially confusing
Comentarii
- Acesta este răspunsul meu preferat. ‘ Explicit este mai bun decât implicit ‘ uneori intră în conflict cu lizibilitatea, simplitatea și DRY. Mai ales atunci când utilizați un cadru precum Django.
Răspundeți
În opinia mea, folosiți îmbunătățește lizibilitatea. Când revizuiesc codul Python, îmi place să văd de unde vine funcția sau clasa dată chiar de unde este folosită. Mă scutește de la derularea în partea de sus a modulului pentru a obține aceste informații.
În ceea ce privește numele lungi ale modulului, folosesc doar cuvântul cheie as
și le dau scurt pseudonime:
import collections as col import foomodule as foo import twisted.internet.protocol as twip my_dict = col.defaultdict() foo.FooBar() twip_fac = twip.Factory()
Ca excepție, folosesc întotdeauna notația from module import something
când mă ocup de __future__
. Pur și simplu nu o puteți face în alt mod când doriți ca toate șirurile să fie unicode în mod implicit în Python 2, de ex.
from __future__ import unicode_literals from __future__ import print_function
Comentarii
- Amin! ” import ca ” este o combinație câștigătoare 🙂
Răspuns
Deși import sys
și from sys import agrv
ambele importă întregul modul sys
, acesta din urmă folosește legarea numelui, astfel încât doar modulul argv
este accesibil restului codului.
Pentru unii oameni acesta ar fi stilul preferat, deoarece face accesibilă doar funcția pe care ați declarat-o explicit.
Cu toate acestea, introduce potențiale conflicte de nume. Ce se întâmplă dacă ați avea un alt modul numit argv
? Rețineți că puteți, de asemenea, să importați explicit funcția și să o redenumiți cu from sys import argv as sys_argv
, o convenție care îndeplinește importul explicit și este mai puțin probabil să acorde spațiu pentru nume coliziuni.
Comentarii
- Deci, cum este
if sys_argv:
mai bun decâtif sys.argv:
? Știu ce înseamnă cea de-a doua afirmație, habar n-am ce înseamnă prima formă fără retrogradarea importanței bizare.
Răspuns
Mi-am pus recent această întrebare. Am cronometrat diferitele metode.
biblioteca de cereri
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
biblioteca 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
biblioteca 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
biblioteca 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
Se pare că eu că există o ușoară diferență de performanță.
Comentarii
- Adăugați într-o căutare de atribute. Pentru a compara
import module
cufrom module import name
corect, adăugați acea căutare de nume laimport module
caz. De exemplu. adăugați liniasys.argv
la testular
etc. Va exista în continuare o diferență, deoarece munca realizată este ușor diferit, deoarece se generează coduri de byt diferite și se execută codepath-uri diferite. - Rețineți că abordez direct această diferență în răspunsul meu; va exista o diferență între utilizarea
import sys
apoi utilizareasys.argv
mii de ori într-o buclă vs.from sys import argv
apoi folosind doarargv
. Dar nu ‘ t. Pentru lucrurile pe care le faceți doar o dată la nivelul global al modulului dvs., ar trebui să optimizați cu ușurință lizibilitatea, nu diferențele microscopice de sincronizare. - Ahhhh! Și am crezut că sunt pe ceva! 🙂 V-am degresat doar răspunsul. Se pare că am sărit pistolul pe acela. Se simte bine să fii umilit.
Răspuns
Privind fragmentele de cod publicate, importând module întregi și făcând referire la module.function
este aproape standardul, cel puțin pentru modulele standard. Singura excepție pare să fie datetime
from datetime import datetime, timedelta
, astfel încât să puteți spune datetime.now()
mai degrabă decât datetime.datetime.now()
.
Dacă sunteți îngrijorat de performanță, puteți spune întotdeauna (de exemplu)
argv = sys.argv
și apoi efectuați codul critic de performanță, deoarece căutarea modulului este deja efectuată. Cu toate acestea, deși acest lucru va funcționa cu funcții / metode, majoritatea IDE-urilor se vor confunda și vor câștiga „t (de exemplu) afișează o legătură / semnătură sursă pentru funcție atunci când este atribuită unei variabile.
Răspuns
Vreau doar să adaug că dacă faci ceva de genul
from math import sin
(sau orice altă bibliotecă încorporată precum sys
sau posix
), atunci sin
fi inclus în documentația pentru modulul dvs. (adică atunci când faceți >>> help(mymodule)
sau $ pydoc3 mymodule
. Pentru a evita acest lucru, importați utilizând:
import math from math import sin as _sin
PS: o bibliotecă încorporată este una care este compilată din cod C și inclusă în Python. argparse
, os
și io
nu sunt pachete încorporate
from … import …
în Python