Zawsze korzystałem z tej metody:
from sys import argv
i używaj argv
z argv . Ale istnieje konwencja korzystania z tego:
import sys
i używając argv przez sys.argv
Druga metoda sprawia, że kod sam się dokumentuje i ja (naprawdę) go przestrzegam. Ale wolę pierwszą metodę, ponieważ jest szybka, ponieważ importujemy tylko potrzebną funkcję, a nie cały moduł (który zawiera więcej bezużytecznych funkcji, które Python zmarnuje czas na ich importowanie). Zauważ, że potrzebuję tylko argv, a wszystkie inne funkcje sys są dla mnie bezużyteczne.
Więc moje pytania są. Czy pierwsza metoda naprawdę sprawia, że skrypt jest szybki? Która metoda jest najbardziej preferowana? Dlaczego?
from … import …
Odpowiedzi:
Importowanie modułu niczego nie marnuje ; moduł jest zawsze w pełni importowany (do
sys.modules
mapowania), więc czy używasz go,import sys
czyfrom sys import argv
nie ma żadnych szans.Jedyną różnicą między tymi dwoma instrukcjami jest to, jaka nazwa jest związana;
import sys
wiąże nazwęsys
z modułem (sosys
->sys.modules['sys']
), afrom sys import argv
wiąże inną nazwęargv
, wskazując prosto na atrybut zawarty w module (soargv
->sys.modules['sys'].argv
). Resztasys
modułu nadal tam jest, niezależnie od tego, czy używasz czegokolwiek innego z modułu, czy nie.Nie ma również różnicy w wydajności między tymi dwoma podejściami. Tak,
sys.argv
musi szukać dwóch rzeczy; musi wyszukaćsys
w twojej globalnej przestrzeni nazw (znajduje moduł), a następnie wyszukać atrybutargv
. I tak, używającfrom sys import argv
możesz pominąć wyszukiwanie atrybutów, ponieważ masz już bezpośrednie odwołanie do atrybutu. Aleimport
oświadczenie wciąż musi wykonać tę pracę, wyszukuje ten sam atrybut podczas importowania i będziesz musiał użyćargv
tylko raz . Gdybyś musiał użyćargv
tysiące razy w pętli, mogłoby to mieć znaczenie, ale w tym konkretnym przypadku tak naprawdę nie jest.Wybór między jednym a drugim powinien zatem opierać się na stylu kodowania .
W dużym module z pewnością skorzystałbym
import sys
; dokumentacja kodu ma znaczenie, a użyciesys.argv
gdzieś w dużym module sprawia, że jest o wiele bardziej zrozumiałe, o czym mówisz, niżargv
kiedykolwiek.Jeśli jedynym miejscem, z którego korzystasz,
argv
jest'__main__'
blok do wywołaniamain()
funkcji, z pewnością użyj tej opcji,from sys import argv
jeśli czujesz się szczęśliwszy z tego powodu:Nadal bym
import sys
tam używał . Wszystkie rzeczy są równe (i są one dokładnie pod względem wydajności i liczby znaków użytych do napisania tego), dla mnie jest to po prostu łatwiejsze.Jeśli importujesz coś zupełnie innego , być może w grę wchodzi wydajność. Ale tylko jeśli wielokrotnie użyjesz określonej nazwy w module , na przykład w krytycznej pętli. Ale tworzenie nazwy lokalnej (w ramach funkcji) będzie jeszcze szybsze:
źródło
from...import
pozwalapackage.attribute
raczej zrobić , niżpackage.subpackage_or_module.attribute
, co może być przydatne, jeśli masz logiczne lub koncepcyjne grupy w pakiecie, ale chcesz sprawić, by było trochę wygodniej dla użytkowników twojego pakietu. (numpy
jak sądzę robi coś takiego)from django.core.management.base import BaseCommand
są lepsze, a wszystko inne (szczególnieimport django
) prowadzi do nieczytelnego kodu. Chociaż podoba mi się ta odpowiedź, myślę, że istnieją pewne biblioteki (a zwłaszcza niektóre frameworki), w których konwencja ma naruszać zwykły import. Jak zawsze, wykorzystaj swoją ocenę tego, co jest najlepsze w danej sytuacji. Ale błąd po stronie jawnej (innymi słowy zgadzam się w przeważającej części).import ... as
, aby znaleźć pakiet do innej nazwy:import package.subpackage_or_module as shortname
.from parent import sub
robi zasadniczo to samo.Istnieją dwa powody przemawiające za używaniem
import module
zamiastfrom module import function
.Pierwsza to przestrzeń nazw. Importowanie funkcji do globalnej przestrzeni nazw grozi kolizjami nazw.
Po drugie, nie jest to istotne dla standardowych modułów, ale jest istotne dla własnych modułów, szczególnie podczas programowania. Jest to opcja dla
reload()
modułu. Rozważ to:Z drugiej strony
Co do prędkości ...
Niezależnie od tego, czy importujesz moduł, czy importujesz funkcję z modułu, Python przeanalizuje cały moduł. Tak czy inaczej moduł zostanie zaimportowany. „Importowanie funkcji” to nic innego jak powiązanie funkcji z nazwą. W rzeczywistości
import module
jest mniej pracy dla tłumacza niżfrom module import func
.źródło
Używam
from import
s, gdy poprawia to czytelność. Na przykład wolę (średniki mają tutaj tylko zaoszczędzić miejsce):zamiast:
Ten ostatni jest dla mnie trudniejszy do odczytania (i napisania), ponieważ zawiera tyle zbędnych informacji. Warto też wiedzieć z góry, jakich części modułu używam.
Wolę zwykłe
import
s, jeśli używam wielu krótkich nazw z modułu:Lub jeśli nazwa jest tak ogólna, że nie ma sensu poza obszarem nazw:
źródło
Moim zdaniem regularne
import
poprawia czytelność. Podczas przeglądania kodu Python lubię widzieć, skąd dana funkcja lub klasa pochodzi właśnie tam, gdzie jest używana. Oszczędza mi to przewijania na górę modułu, aby uzyskać te informacje.Jeśli chodzi o długie nazwy modułów, po prostu używam
as
słowa kluczowego i daję im krótkie aliasy:Jako wyjątek zawsze używam
from module import something
notacji, kiedy mam do czynienia z__future__
modułem. Po prostu nie możesz tego zrobić w inny sposób, jeśli chcesz, aby wszystkie ciągi były domyślnie Unicode w Pythonie 2, npźródło
Mimo,
import sys
ifrom sys import agrv
zarówno importować całysys
moduł, korzysta on wiążący tak nazwać tylkoargv
moduł dostępny jest do reszty kodu.Dla niektórych osób byłby to preferowany styl, ponieważ udostępnia tylko funkcję, którą wyraźnie podałeś.
Wprowadza jednak potencjalne konflikty nazw. Co jeśli masz inny moduł o nazwie
argv
? Zauważ, że możesz również jawnie zaimportować funkcję i zmienić jej nazwęfrom sys import argv as sys_argv
, zgodnie z konwencją, która spełnia jawny import i rzadziej powoduje kolizje przestrzeni nazw.źródło
if sys_argv:
coś lepszego niżif sys.argv:
? Wiem, co oznacza drugie zdanie, nie mam pojęcia, co oznacza pierwsza forma bez cofania się do dziwnego importu.Niedawno zadałem sobie to pytanie. Zmierzyłem czas różnych metod.
biblioteka żądań
biblioteka beautifulsoup
biblioteka json
biblioteka sys
Wydaje mi się, że istnieje niewielka różnica w wydajności.
źródło
import module
zfrom module import name
prawidłowo dodać , że nazwa odnośnika doimport module
sprawy. Np. Dodaj linięsys.argv
doar
testu itp. Nadal będzie różnica, ponieważ wykonywana praca jest nieco inna, ponieważ generowany jest inny kod bajtowy i wykonywane są różne ścieżki kodowe.import sys
a użyciemsys.argv
tysięcy razy w pętli w porównaniu zfrom sys import argv
użyciem tylkoargv
. Ale ty nie. W przypadku rzeczy, które robisz tylko raz na poziomie globalnym modułu, naprawdę powinieneś zoptymalizować czytelność, a nie mikroskopijne różnice w taktowaniu.Przeglądanie opublikowanych fragmentów kodu, importowanie całych modułów i odwoływanie się do nich
module.function
jest prawie standardem, przynajmniej dla standardowych modułów. Wydaje się, że jedynym wyjątkiem jestdatetime
więc możesz powiedzieć
datetime.now()
raczej niżdatetime.datetime.now()
.Jeśli martwisz się wydajnością, zawsze możesz powiedzieć (na przykład)
a następnie zrób kod krytyczny dla wydajności, ponieważ wyszukiwanie modułu jest już zakończone. Jednak chociaż będzie to działać z funkcjami / metodami, większość IDE będzie się mylić i nie będzie (na przykład) wyświetlać linku / podpisu źródłowego dla funkcji, gdy jest ona przypisana do zmiennej.
źródło
Chcę tylko dodać, że jeśli robisz coś takiego
(lub dowolną inną wbudowaną bibliotekę, taką jak
sys
lubposix
),sin
zostaną one dołączone do dokumentacji modułu (tj. kiedy to zrobisz>>> help(mymodule)
lub$ pydoc3 mymodule
. Aby tego uniknąć, importuj za pomocą:PS: biblioteka wbudowana to taka, która jest skompilowana z kodu C i dołączona do Pythona.
argparse
,os
Aio
nie są wbudowane w pakietachźródło