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ți package.attribute în loc de package.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 special import 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ât if 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 cu from module import name corect, adăugați acea căutare de nume la import module caz. De exemplu. adăugați linia sys.argv la testul ar 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 utilizarea sys.argv mii de ori într-o buclă vs. from sys import argv apoi folosind doar argv. 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

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *