Sintaksa i semantika Pajtona
Sintaksa programskog jezika Pajton je niz pravila koja definišu kako će program u Pajtonu biti napisan i interpretiran (sa računarske strane kao i strane ljudskog čitaoca).
Filozofija dizajna
[uredi | uredi izvor]Pajton je dizajniran da bude veoma čitljiv jezik. Ima relativno neopterećen vizuelni dezen i često koristi engleske reči tamo gde drugi jezici koriste znakove interpunkcije. Pajton cilja ka jednostavnosti i opštost u dezenu njegovih sintaksi, osvrćujući se na "Treba biti jedan - i samo jedan - očigledan način da se to uradi", iz "Zen Pajtona".
Ovo se kosi sa načinom rada Perl i Rubi, "postoji više načina da se to uradi".
Ključne reči
[uredi | uredi izvor]Pajton ima sledeće ključne reči ili rezervisane reči; one ne mogu biti korišćene kao identifikatori.[1]
and
as
assert
break
class
continue
def
del
elif
else
except
exec
False
finally
for
from
global
if
import
in
is
lambda
None
nonlocal
not
or
pass
print
raise
return
True
try
while
with
yield
Uvlačenje
[uredi | uredi izvor]Pajton koristi vajtspejs da ograniči programske blokove, prateći ofsajd pravilo. Pajton pozajmljuje ovo svojstvo od njegovog prethodnika ABC: umesto interpunkcija ili ključnih reči, on koristi uvlačenje da prikaže blok u kome se odvija programski kod.
U takozvanim "slobodno-formatskim" jezicima, koja koriste strukturu blokova iz ALGOL, blokovi koda su razdvojeni zagradama ({ }
) ili ključnim rečima. U mnogim konvencijama koda za ove jezike, programeri konvenciono pišu kod u okviru bloka, da ga vizuelno razdvoje od okolnog koda.
Zamislite funkciju, foo
, koja sadrži jedan parametar, x
, i ako je parametar 0 pozvaće bar
i baz
, u suprotnom pozvaće qux
, prolazeći x
, kao i pozvati sebe rekurzivno, prolazeći x-1
kao parametar. Evo su implementacije ove funkcije i u C i Pajtonu:
foo
funkcija u C sa stilom pisanja K&R:
void foo(int x)
{
if (x == 0) {
bar();
baz();
} else {
qux(x);
foo(x - 1);
}
}
foo
funkcija u Pajtonu:
def foo(x):
if x == 0:
bar()
baz()
else:
qux(x)
foo(x - 1)
Pajton se koristi konvencijom kojom se programeri u ALGOL stilu jezika često koriste. Štaviše, u friform sintaksi, od kad je uvlačenje ignorisano, dobro uvlačenje ne može biti forsirano od strane interpretatora ili kompajlera. Nepravilno uvučen kod može biti razumet sa ljudske strane različito nego što to može kompajler ili interpretator. Na primer: Nepravilno uvlačenje u C:
for (i = 0; i < 20; ++i)
a();
b();
c();
Kod je bio namenjen da pozove funkcije a()
i b()
20 puta. Ali, the ponavljajući blok koda je samo {a();}
. Kod poziva a()
20 puta, i zatim zove b()
i c()
samo jedanput i jednu i drugu. Čitači ovog koda mogu biti prevareni nepravilnim redosledom pozivanja funkcija b i c.
Greške uvlačenja u Pajtonu:
def foo(x):
if x == 0:
bar()
baz()
else:
qux(x)
foo(x - 1)
Ovde, u suprotnosti sa gore navedenim Pajton foo
primerom, pozivna funkcija foo(x - 1)
biva uvek izvršena, rezultujući se u neprekidnoj rekurziji. Takva vrsta greške uvlačenja (kao što je slučajno brisanje uvlačenja u zadnjem redu) je moguće samo u programskim jezicima koja ne obeležavaju blokove sa jasnim oznakama, kao što su zakrivljene zagrade u C. U konkretno ovom primeru čak ni editor sa automatskim uvlačenjem ne može sprečiti pogrešnp ponašanje ovog Pajton koda. Ova ne namerna greška može lako proći u bazni kod bez prethodnog primećivanja od programera. U mnogim drugim programskim jezicima ovo ne bi bilo moguće (brisanje krajnjih blokova obeležja u C bi prikazalo kompajlersku grešku) i ovo čini Pajton sintakse mnogo manje robusnim u odnosu na mnoge druge jezike.
Oba znakova, razmak i tab su trenutno prihvaćeni kao forme za uvlačenje u Pajtonu. Pošto mnogo alata ih vizuelno ne razlikuje, mešanje razmaka i tab-a može napraviti bagove koji zahtevaju napore da se nađu. Štaviše, rutine formatiranja koja brišu vajtspejs primer, Forum (internet)—mogu uništiti sintaksu Pajton programa, gde bi kod programa sa zagradama bilo teže da se pročita.
Mnogi popularni programski editori rukuju Pajtonovim uvlačenjem bez problema, ponekad nakon omogućivanja u opcijama konfiguracija.
Struktura podataka
[uredi | uredi izvor]Otkako je Pajton dinamično pisan jezik, Pajton vrednosti, ne promenljive, nose tip. Ovo ima implikacije na mnogo aspekata na način na koji ovaj jezik funkcioniše.
Sve vrednosti u Pajtonu nose reference prema objektima, i ove reference takođe prolaze u funkcije; funkcija ne može da promeni vrednost promenljive reference u pozivnoj funkciji (ne sasvim, pogledajte ispod). Neki ljudi (uključujući Gvido van Rosum samog) su zvali ovu parametarno-prolaznu šemu "Pozvati po referenci objekta." Referenca objekta znači ime, i prolazna referenca je "alias", na primer kopija reference na isti objekat, baš kao i u C/C++. Vrednost objekta može biti promenjena u pozivnoj funkciji sa "alias", na primer:
>>> alist = ['a', 'b', 'c']
>>> def myfunc(al):
... al.append('x')
... print al
...
>>> myfunc(alist)
['a', 'b', 'c', 'x']
>>> alist
['a', 'b', 'c', 'x']
Funkcija "myfunc" je promenila vrednost "alist" sa formalnim argumentom "al", koji je alias od "alist". Ali, bilo koji pokušaj promene samog aliasa ne bi imalo bilo kakav efekat na originalni objekat. U Pajtonu, ne-najdublje-lokalno i ne-deklarisano-globalno dostupni nazivi su svi "aliasi".
Pored dinamično pisanih jezika, Pajton je osrednje proveravan u pisanju. Implicitna konverzija je definisana za numeričke tipove (kao i za bulean), tako da osoba može validno umnožiti kompleksan broj sa dugim celim brojem (na primer) bez eksplicitnog kastinga. Ali, ne postoji implicitna konverzija između (na primer) brojeva i stringova; string je nevažeći argument matematičkoj funkciji koja očekuje broj.
Tipovi baza
[uredi | uredi izvor]Pajton ima širok opseg opštih tipova podataka. Pored konvencionalnih celih brojeva i decimalne aritmetike, on providno podržava it aritmetiku arbitarne preciznosti, kompleksni brojevi, i brojeve u decimalnom zapisu.
Pajton podržava širok spektar string operacija. Stringovi u Pajtonu su nepromenljivi, tako da string operacija kao što je substitucija karaktera, da u drugim programskim jezicima može promeniti string u mestu, vraća novi string u Pajtonu.
Tipovi prikupljanja
[uredi | uredi izvor]Jedan od korisnih aspekata Pajtona je koncept prikupljanja tipova. Generalno, kolekcija je objekat koji sadrži druge objekte na način koji je lako referenciran ili indeksovan. Kolekcije dolaze u dva osnovna oblika: sekvence i mapiranje.
Poređani sekvencioni tipovi su liste, torke, i stringovi. Sve sekvence su indeksirane po poziciji (od 0 do dužine - 1) i svi sem stringova mogu sadržati bilo koji tip objekta, uključujući više tipova u istoj sekvenci. Oba stringa i tuplea su nepromenljivi, čineći ih savršenim kandidatima za ključeve rečnika (pogledajte ispod) u mestu.
Mapiranje, u drugu ruku, su nepoređani tipovi implementirani u formi rečnika čija "mapa" je skup nepromenljivih ključeva odgovarajućim elementima (skoro kao matematička funkcija). Na primer, osoba može definisati rečnik da sadrži string "toast"
mapiran na broj 42 ili obrnuto. Ključevi u rečniku moraju biti nepromenljivog Pajton tipa, kao što je to integer ili string, zato što su implementirani preko heš funkcije. Ovo mnogo ubrzava pretragu, ali zahteva da se ključevi ne menjaju (što takođe rezultira lošom raspodelom u rečniku).
Rečnici su takođe centar unutrašnjosti jezika jer se oslanjaju na jezgro svih Pajton objekata i klasa: mapiranje između promenljivih naziva (stringova) i vrednosti čija imena referenci su skladišteni kao rečnici (pogledajte sistem objekata). Pošto su ovi rečnici direktno dostupni (preko svojstva objekta __dict__
), metaprogramiranje je jednostavan i prirodan proces u Pajtonu.
Skup skupljajućeg tipa je dodat u jezgro jezika u verziji 2.4. Set je neindeksovana, neuređena kolekcija koja ne sadrži duplikate, i implementira set theoretic operacije kao što su union, preseci, difference, symmetric difference, i podskup testiranje. Postoje dva tipa setova: set
i frozenset
, jedina razlika je ta što je set
promenljiv a frozenset
nepromenljiv. Elementi u setu moraju biti u mogućnosti za hešovanje i da budu nepromenljivi. Tako da, na primer, frozenset
može biti element regularnog set
gde obrnuto nije moguće.
Pajton takođe pruža široku kolekciju manipulativnih mogućnosti kao što je ugrađeno proveravanje sadržaja i protokol generičnog ponavljanja.
Sistem objekta
[uredi | uredi izvor]U Pajtonu, sve je objekat, čak i klase. Klase, kao i objekti, imaju klase, koja su poznata kao njihova metaklasa. Pajton takođe podržava višestruko nasledstvo i miksins.
Jezik podržava široku introspekciju tipova i klasa. Tipovi mogu biti čitani i upoređivani—tipovi su instance type
. Svojstva objekta mogu biti pretvorena u rečnike.
Operatori mogu biti preopterećeni u Pajtonu definisanjem specijalnog člana funkcija—na primer, definisanje __add__
na klasu omogućava osobu da koristi +
operator na korisnike iz te klase.
Literali
[uredi | uredi izvor]Stringovi
[uredi | uredi izvor]Pajton ima razne oblike literala.
Normalni string literali
[uredi | uredi izvor]Mogu se koristiti obični kao i dvojni navodnici za navođenje stringova. Za razliku u Unix jezicima, Perl ili Perl-inspirisani jezici kao što su Rubi ili Gruvi, obični i dvojni navodnici rade identično, na primer, ne postoji string umetanje od $foo izraza. Ali, umetanje može biti izvršeno koristeći % string-format operator, kao što je Perl naredba
print "I just printed $num pages to the printer $printer\n"
jednaka Pajton naredbi
print("I just printed %s pages to the printer %s" % (num, printer))
Ali, trenutni standard ovog načina string formatiranja je da se koristi format metoda stringova:
print("I just printed {0} pages to the printer {1}".format(num, printer))
Literali višelinijskih stringova
[uredi | uredi izvor]Postoje i višelinijski stringovi, koji počinju i završavaju se sa redom od tri običnih i dvojnih navodnika i rade kao here documents u Perl i Rubi.
Običan primer sa umetanjem promenljivih (koristeći % string-format operator) je:
print("""Dear %(recipient)s,
I wish you to leave Sunnydale and never return.
Not Quite Love,
%(sender)s
""" % {'sender': 'Buffy the Vampire Slayer', 'recipient': 'Spike'})
Raw stringovi
[uredi | uredi izvor]Konačno, svi prethodno pomenuti oblici stringova dolaze u "raw" oblicima, i veoma su korisni za regularne izraze; porediti "@-quoting" u C#. Raw stringovi su originalno namenjeni za regularne izraze. Zbog ograničenja tokenajzera, raw stringovi mogu da nemaju kosu crtu.[1] Pravljenje raw stringa koja drži Windows putanju koja se završava sa kosom crtom zahteva neki oblik napora (često, koristeći se kosam crtama unapred umesto unazad, od kad Windows prihvata oba).
Primeri uključuju:
# A Windows path, even raw strings cannot end in a backslash
r"C:\Foo\Bar\Baz\" # raises SyntaxError
r"C:\Foo\Bar\Baz\ ".rstrip() # avoids the error by adding and removing trailing space
# A regular expression matching a quoted string with possible backslash quoting
r'"([^"\\]|\\.)*"'
# Reverse the arguments in a two-arg function call, e.g. foo(2, bar) -> foo(bar, 2).
re.sub(r'\(([^,]*?),([^,]*?)\)', r'(\2, \1)', code)
# Note that this won't work if either argument has parens or commas in it.
Povezivanje u lanac susednih string literala
[uredi | uredi izvor]String literali pojavljujući se spojeno i razdvojeni samo razmakom (uključujući nove redove), su dozvoljeni i nagomilavani u jedan duži string.[1] title = "One Good Turn: " \'A Natural History of the Screwdriver and the Screw' </syntaxhighlight>je jednako
title = "One Good Turn: A Natural History of the Screwdriver and the Screw"
Brojevi
[uredi | uredi izvor]Numerički literali u Pajtonu su normalnog tipa, na primer 0
, -1
, 3.4
, 3.5e-8
.
Pajton ima proizvoljnu dužinu celih brojeva i automatski povećavaju prostorno skladište po potrebi. Do Pajtona verzije 3, postojale su dva tipa celih brojeva: tradicionalno prostorno fiksirani celi brojevi i "dugački" celi brojevi proizvoljnog domena. Konverzija u "dugačke" cele brojeve je rađeno automatski po potrebi, i programer obično nije morao da bude svestan ova dva tipa celih brojeva. U novijim verzijima jezika, prostorno-fiksni celi brojevi su potpuno nestali.
Pajton podržava normalne decimalne brojeve, koji su napravljeni kada se koristi tačka u literalu (npr. 1.1
), kada su celi broj i decimalni broj korišćeni u izrazu, ili kao rezultat neke matematičke operacije (deljenje /
operatorom, ili stepenovanje negativnom komponentom).
Pajton takođe podržava kompleksne brojeve. Kompleksni brojevi su naznačeni sa J
ili j
sufiksom, npr. 3 + 4j
.
Liste, torke, setovi, rečnici
[uredi | uredi izvor]Pajton ima sintaksnu podršku za pravljenje skladišnih tipova.
Liste (klasa list
) su promenljive sekvence stavki proizvoljnih tipova, i mogu biti napravljene ili sa posebnom sintaksom
a_list = [1, 2, 3, "a dog"]
ili koristeći normalne objekte
a_second_list = list()
a_second_list.append(4)
a_second_list.append(5)
Torke (klasa tuple
) su promenljive sekvence stavki proizvoljnih tipova. Postoji i posebna sintaksa za pravljenje torki
a_tuple = 1, 2, 3, "four"
Iako su torke pravljene za razdvajanje stavki sa zarezima, ceo koncept se obično svodi na poboljšanje čitljivosti koda. Prazna torka se označava sa ()
.
Setovi (klasa set
) su promenljiva skladišta stavki promenljivih tipova, bez duplikata. Stavke nisu poređane. Sintaksa za pravljenje setova se pojavila u Pajtonu 2.7/3.0
some_set = {0, (), False}
U ranijim verzijama Pajtona, setovi bi bili napravljeni pozivanjem set klase sa listom argumenata. Pajton setovi su veoma slični kao matematički setovi, i podržavaju operacije kao što su preseci and unije.
Pajton takođe ima frozenset
klasu za nepromenljive setove.
Rečnici (klasa dict
) su promenljivo mapirani ključevi sa odgovarajućim vrednostima. Pajton ima posebnu sintaksu za pravljenje rečnika ({key: value}
)
a_dictionary = {"key 1":"value 1", 2:3, 4:[]}
Sintaksa rečnika je slična set sintaksi, razlika je u prisustvu kolona. Prazan literal {}
rezultuje u praznom rečniku umesto praznom setu, koji je zatim napravljen koristeći ne-literalni konstruktor: set()
.
Operatori
[uredi | uredi izvor]Aritmetika
[uredi | uredi izvor]Pajton sadrži +
, -
, *
, /
, %
(kongurenciju), i **
(stepenovanje) operatore.
Tradicionalno, x / y
izvrašavalo je celobrojno deljenje ako su x
i y
bili celi brojevi (vraćajući samo brojeve do decimale), i vraćalo je decimalni zapis ako je bar jedan od njih bio u takvom zapisu. Ali, pošto je Pajton dinamično pisan jezik, nije uvek bilo moguće znati koja operacija je bila izvrašavana, što je dovodilo do bagova. Na primer, sa
def mean(seq):
return sum(seq) / len(seq)
Poziv na mean([3.0, 4.0])
bi vratilo 3.5, ali mean([3, 4])
bi vratilo 3. Ako ovo nije bilo namerno ponašanje, bilo je potrebno uraditi nešto poput
def mean(seq):
return float(sum(seq)) / len(seq)
Da bi se izbegao ovaj problem, došlo je do promene na način na koji Pajton delilac funkcioniše. U pajtonu 2.2, novi operator //
je uveden za deljenje, kako za celobrojne tako i za decimalne argumente. Operator /
je promenjen tako da količnik dva celobrojna broja su vraćala decimalan zapis, ali za povratnu kompatibilnost, ovakvo ponašanje bi moralo biti eksplicitno zatraženo sve do Pajtona 3.0.
Operatori poređenja
[uredi | uredi izvor]Obični operatori poređenja kao što su ==
, <
, >=
, i tako dalje, su korišćeni za razne vrednosti. Brojevi, stringovi, sekvence, i mapiranje - svi oni mogu biti poređeni međusobom. Ali, različiti tipovi (kao što su str
i int
) su definisani da imaju stalni relativni redosled; ovo je smatrano istorijskim kapricom i nije dozvoljen od Pajtona 3.0.
Lančani izrazi poređenja kao što su a < b < c
imaju skoro isto značenje kao i u matematici, za razliku od neobičnog smisla u C i sličnim jezicima. Uslovi su proveravani i poređivani po redosledu. Operacija ima kratkotrajnu semantiku, što znači da je evaluacija zagarantovana da prestane čim presuda postane jasna: ako je a < b
false, c
nije nikada evaluirano jer izraz jednostavno ne može biti tačan više.
Za iraze bez neželjenih efekata, a < b < c
je jednako a < b and b < c
. Ali, postoji značajna razlika kada izrazi imaju neželjene efekte. a < f(x) < b
će da evaluira f(x)
tačno jednom, dok a < f(x) and f(x) < b
će da ga evaluira dva puta ako je vrednost za a
manje od f(x)
i jednom ako nije.
Logički operatori
[uredi | uredi izvor]Pajton 2.2 i raniji nemaju eksplicitni bulean tip. U svim verzijama Pajtona, bulean operatori tretiraju nulu ili prazne vrednosti kao što su ""
, 0
, None
, 0.0
, []
, i {}
kao false, dok u generalnom tretiranju ne-prazne, ne-nule kao true. U Pajtonu 2.2.1 bulean konstante True
i False
su dodate u jezik (umesto kao 1 i 0). Operatori binarnih poređenja kao što su ==
i >
vraćaju True
ili False
.
Operatori bulean and
i or
koriste minimalnu evaluaciju. Na primer, y == 0 or x/y > 100
nikada neće podići deljenje nulom izuzetak. Ovi operatori vraćaju vrednost iz poslednje evaluacije, umesto True
ili False
. Tako da izrazi (4 and 5)
evaluiraju 5
, i (4 or 5)
evaluira u4
.
Funkcionalno programiranje
[uredi | uredi izvor]Kao što je pomenuto gore, još jedna prednost Pajtona je dostupnost stila funkcionalno programiranje. Kao što se očekuje, ovo čini pravljenje listi i ostalih kolekcija mnogo jednostavnije.
Lista shvatanja
[uredi | uredi izvor]Jedna takva konstrukcija je lista shvatanja, koja može biti napisana u sledećem formatu:
L = [mapping-expression for element in source-list if filter-expression]
Koristeći listu shvatanja da se izračunaju prvih pet stepena dvojke:
powers_of_two = [2**n for n in range(1, 6)]
Kviksort algoritam može biti napisan elegantno (ali neefikasno) koristeći se listom shvatanja:
def qsort(L):
if L == []:
return []
pivot = L[0]
return (qsort([x for x in L[1:] if x < pivot]) +
[pivot] +
qsort([x for x in L[1:] if x >= pivot]))
Funkcije prve klase
[uredi | uredi izvor]U Pajtonu, funkcije su objekti prve klase koje mogu biti napravljene i pomerane dinamično.
Pajtonova ograničena podrška za anonimne funkcije je lambda
.
Pošto je dostupnost potpuno anonimnih funkcija nepostojeće, glavna korist lambda funkcija je imenovanje funkcija. Lambde su ograničene da sadrže izraze umesto naredbi, iako kontrola toka može biti implementirana manje elegantno sa lambda koristeći se sa kratkim spojem.[2]
Zatvaranje
[uredi | uredi izvor]Pajton ima podršku za leksičko zatvaranje od verzije 2.2. Evo primera:
def derivative(f, dx):
"""Return a function that approximates the derivative of f
using an interval of dx, which should be appropriately small.
"""
def function(x):
return (f(x + dx) - f(x)) / dx
return function
Pajtonova sintaksa, ponekad može naterati programere drugih jezika da zatvaranje nije podržano. Obim promenljive u Pajtonu je prećutno određen obimom kojom osoba dodeljuje vrednosti promenljive, osim ako je obim eksplicitno deklarisan sa global
ili nonlocal
.[3]
Vezivanje zatvaranja imena u neku vrednost nije promenljivo u okviru funkcije. Dato:
def foo(a, b):
print 'a: %r' % a
print 'b: %r' % b
def bar(c):
b = c
print 'b*: %r' % b
bar(a)
print 'b: %r' % b
foo(1, 2)
će dati:
a: 1
b: 2
b*: 1
b: 2
i možete videti da b
, kao što je vidljivo iz obima zatvaranja, zadržava vrednost koju je imalo; promenjeno vezivanje od b
u okviru funkcije nije propagiralo vani. Zaobilaznica oko ovoga je korišćenje promenljive vrednosti, zatim promeniti tu vrednost, ne vezivanje. Na primer, lista sa jednim elementom.
Generatori
[uredi | uredi izvor]Uvedeni u Pajtonu 2.2 kao opciona mogućnost, a završena u verziji 2.3, generatori su Pajtonov mehanizam za lenje evaluacije funkcije koja bi inače vratila previše praznog ili računski intenzivnu listu.
Ovo je primer lenjeg generisanja prostih brojeva:
from itertools import count
def generate_primes(stop_at=0):
primes = []
for n in count(2):
if 0 < stop_at < n:
return # raises the StopIteration exception
composite = False
for p in primes:
if not n % p:
composite = True
break
elif p ** 2 > n:
break
if not composite:
primes.append(n)
yield n
Da koristite ovu funkciju, prosto je pozovite:
for i in generate_primes(): # iterate over ALL primes
if i > 100:
break
print(i)
Definicija generatora se pojavljuje identično kao što se zove, osim ključne reči yield
koja se koristi umesto return
. Ali, generator je objekat sa stalnim stanjem, koji može rekurzivno ulaziti i izlaziti isti obim. Pozivanje generatora može biti izvršeno onda umesto liste, ili druge strukture čiji elementi će biti ponovljeni. Kada god for
petlja u primeru zahteva sledeću stavku, generator biva pozivan, koji prinosi sledeću stavku.
Generatori ne moraju biti beskonačni kao kod primera sa prostim brojevima gore. Kada generator završi, unutrašnji izuzetak se izdiže koji naznačava bilo koje pozivne kontekste da nema više vrednosti. for
petlja ili drugo ponavljanje se zatim završava.
Izrazi generatora
[uredi | uredi izvor]Uvedeno u Pajtonu 2.4, izrazi generatoru su lenje evaluacije jednake listi shvatanja. Koristeći se generatorom prostih brojeva od malopre, možemo definisati lenju, ali ne tako neograničenu kolekciju.
from itertools import islice
primes_under_million = (i for i in generate_primes() if i < 1000000)
two_thousandth_prime = islice(primes_under_million, 1999, 2000).next()
Većina memorije i vremena potrebno za generisanje ovoliko prostih brojeva neće biti iskorišćeno dok se ne pristupi potrebnom elementu. Nažalost, ne možete izvesti jednostavno indeksiranje i presecanje generatora, ali mnogi se koriste modulima itertools ili "smotaj sam svoju" petljama. U suprotnosti, lista shvatanja je funkcionalno jednaka, ali i pohlepna u izvođenju celokupnog posla:
primes_under_million = [i for i in generate_primes(2000000) if i < 1000000]
two_thousandth_prime = primes_under_million[1999]
Lista shvatanja će odmah napraviti veliku listu (sa 78498 stavki, u primeru, ali prolazno praveći listu prostih brojeva ispod dva miliona), iako su nikada ne pristupi mnogim elementima. Generator shvatanja je više škrto.
Rečnik i set shvatanja
[uredi | uredi izvor]Dok su liste i generatori imali shvatanja/izraze, u Pajtonu verzijama starijim od 2.7 druga ugrađena kolekciona tipa Pajtona (dicts i sets) su morala biti uvedena u korišćenje listi i generatora:
>>> dict((n, n*n) for n in range(5))
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
Pajton 2.7 i 3.0 spajaju sve kolekcione tipove uvodeći dict i set shvatanja, slično listi shvatanja:
>>> [ n*n for n in range(5) ] # regular list comprehension
[0, 1, 4, 9, 16]
>>>
>>> { n*n for n in range(5) } # set comprehension
{0, 1, 4, 16, 9}
>>>
>>> { n: n*n for n in range(5) } # dict comprehension
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
Objekti
[uredi | uredi izvor]Pajton podržava mnogobrojne programske tehnike za objekte. Dozvoljava polimorfozu, i to ne samo u okviru klase hijerarhije, već i pisanje dak-tajpingom. Bilo koji objekat može biti korišćen za bilo koji tip, i radiće sve dok ima pravilne metode i atribute. Sve u Pajtonu je objekat, uključujući klase, funkcije, brojeve i module. Pajton takođe ima podršku za metaklase, naprednu alatku namenjenu za unapređivanje funkcionalnosti klasa. Prirodno, nasledstvo, uključujući višestruko nasledstvo, je podržano. Ima ograničenu podršku za privatne promenljive koristeći se name manglingom. Pogledajte "Klase" odeljak ovog uputstva za detalje. Mnogi korisnici Pajtona nemaju potrebu za privatne promenljive. Slogan "Svi smo ovde odgovorni korisnici" je korišćen da se opiše ovaj stav.[4] Neki smatraju skrivanje informacija "nepajtonski", u kome se predlaže da klasa u pitanju sadrži ne estetski privlačne intervale. Kakogod, najjači argument za mengling imena je prevencija nepredvidivog slamljanja programa: uvodeći novu javnu promenljivu u superklasi može slomiti subklase ako ne koriste "privatne" promenljive.
Iz uputstva: Kao što je tačno za module, klase u Pajtonu ne stavljaju apsolutnu prepreku između definicije i korisnika, već se oslanjaju na učtivost korisnika da ne "probije u definiciju."
U verziji Pajtona 2.2, "novi stil" klasa su uvedeni. Sa novim stilom klasa, objekti i tipovi su ujedinjeni, dozvoljavajući subklasovanje. Čak i potpuno novi tipovi mogu biti definisani, završavajući poručeno ponašanje za infix operatore. Ovo dozvoljava da se mnoge radikalne stvari urade sintatički u Pajtonu. Nova metoda poredka rezolucije za višestruka nasledstva su takođe uvedena u Pajtonu 2.3. Takođe je moguće pokretati ručno poručen kod dok se pristupa ili podešava atributima, detalji ovih tehnika su se menjali tokom Pajton verzija.
With naredbe
[uredi | uredi izvor]Naredbe "with" rade sa izvorima[1]. Jedna funkcija je pozvana prilikom ulaska u domen i još jedna prilikom izlaska. Ovo onemogućava zaboravljanje na brisanje izvora i takođe radi sa više komplikovanim situacijama kao što su izuzeci.
Svojstva
[uredi | uredi izvor]Svojstva dozvoljavaju specifično definisane metode da budu pozvane na primer objekta koristeći se istom sintaksom kao i za pristup atributu. Primer klase koja definiše neka svojstva je:
class MyClass(object):
def get_a(self):
return self._a
def set_a(self, value):
self._a = value - 1
a = property(get_a, set_a, doc="Off by one a")
# Python 2.6 style
class MyClass(object):
@property
def a(self):
return self._a
@a.setter # makes the property writable
def a(self, value):
self._a = value - 1
Deskriptori
[uredi | uredi izvor]Klasa koja definiše jednu ili više specijalnih metoda __get__(self,instance,owner), __set__(self,instance,value), __delete__(self,instance) mogu biti korišćeni kao deskriptori. Pravljenje primera deskriptora kao člana druge klase čini primer svojstvom druge klase.
Klase i statične metode
[uredi | uredi izvor]Pajton dozvoljava pravljenje metoda klasa i statičnih metoda korišćenjem @classmethod i @staticmethod dekoratorima. Prvi argument metode klase je objekat klase umesto samo-referentnosti na primer. Statična metoda nema specijalan prvi argument. Niti primer, ni klasa objekta ne prolazi u statičnu metodu.
Izuzeci
[uredi | uredi izvor]Pajton podržava (i višestruko se koristi) oslanjanjem na izuzetke za testiranje grešaka i ostalih nepredvidivih događaja u programu. Zaista, moguće je zaklopiti izuzetak izazvan sintaksnom greškom.
Stil Pajtona poziva korišćenje izuzetaka kada god postoje uslovi za pojavljivanje grešaka. Preče od testiranja pristupa fajlu ili izvoru pre nego što se zapravo iskoristi, konvenciono je u Pajtonu da se samo nastavi i proba da se iskoristi, hvatajući izuzetke ako je pristup odbijen.
Izuzeci su često korišćeni kao alternativa if
-bloku, posebno u nitnim situacijama. Često pozvan moto je EAFP, ili "It is Easier to Ask for Forgiveness than Permission,"[5] koji je pripisan Grejs Hoper.[6] U prvom primeru koda, postoji eksplicitna provera za atribute (npr. "pita za dozvolu"):
if hasattr(spam, 'eggs'):
ham = spam.eggs
else:
handle_error()
Drugi primer prati EAFP način:
try:
ham = spam.eggs
except AttributeError:
handle_error()
Ova dva primera koda imaju isti efekat, gde nema razlike u performansama. Kada spam
ima svojstvo eggs
, EAFP primer će raditi mnogo brže. Kada spam
nema svojstvo eggs
("poseban" primer), EAFP primer će raditi sporije. Pajton profajler može biti korišćeno u posebnim slučajevima da se izmeri performansa karakteristika. Ako su posebni primeri retki, onda EAFP verzija će imati superiornu performansu u odnosu na alternativu. Takože, zaobilazi celokupnu klasu time-of-check-to-time-of-use (TOCTTOU) raljivosti, ostalih retkih slučajeva,[7] i kompatibilni su sa duck typing-om. Loše strane EAFP su da može biti korišćen samo sa naredbama; izuzetak ne može biti uhvaćen u generatoru izraza, listi razumevanja, ili lambda funkciji.
Komentari i dokstringovi
[uredi | uredi izvor]Pajton ima dva načina da opiše kod u Pajtonu. Jedan je korišćenjem komentara da se naznače koji delovi koda radi šta. Komentari u jednom redu počinju sa znakom hešteg ("#") i završavaju se na kraju istog reda. Komentari koji imaju više redova se pišu korišćenjem višelinijskih stringova (sa """
na svakom kraju) koji nije korišćen u zadatku ili na drugi način evaluiran, ali stoji između drugih naredbi.
Komentarisanje dela koda:
def getline():
return sys.stdin.readline() # Get one line and return it
Komentarisanje dela koda u više redova:
def getline():
return sys.stdin.readline() """this function
gets one line
and returns it"""
Dokstringovi (dokumentacioni stringovi), su stringovi koji se nalaze samostalno bez zadatka kao prvonamenjeni red u okviru modula, klase, metode ili funkcije, automatski postavljajući svoj sadržaj kao svojstvo imenovano sa __doc__
, koji je namenjen za skladištenje opisa svrhe objekta koja je čitljiva od strane korisnika, kao i ponašanje i način korišćenja. Ugrađena help
funkcija generiše svoj izlaz iz __doc__
svojstava. Takvi stringovi mogu biti razdvojeni sa "
ili '
za jednoredne stringove, ili višeredno ako se koristi """
ili '''
Kakogod, stil uputstva za jezik kaže da trostruki navodnici ("""
) su preferirani i za jdnoredne i višeredne dokstringove.
Jednoredni dokstring:
def getline():
"""Get one line from stdin and return it."""
return sys.stdin.readline()
Višeredni dokstring:
def getline():
"""Get one line
from stdin
and return it."""
return sys.stdin.readline()
Dokstringovi mogu biti veliki koliko to programer želi i da sadrži razmake između redova. U suprotnosti sa komentarima, dokstringovi su po sebi objekti Pajtona i deo su interpretiranog koda koji Pajton pokreće. To znači da pokrenut program može povratiti svoje dokstringove i da manipulište tim informacijama. Ali normalno korišćenje je davanje ostalim programerima informacije kako pozvati objekat koji se pojavljuje u dokstringu.
Postoje dostupne alatke koje mogu izvaditi dokstring da generiše API dokumentaciju iz koda. Dokstring dokumentacija takođe može biti pristupana iz interpretatora sa help()
funkcijom, ili iz ljuske sa pajdok komandom pydoc
.
Standard modula doctest se koristi interakcijama kopiranim iz sesija ljuske Pajtona u dokstringovima, da se prave testovi.
Opisi funkcija
[uredi | uredi izvor]Opisi funkcija su definisani u PEP 3107. Oni dozvoljavaju pričvršćivanje datoteka na argumente i povratku rezultata od funkcije. Ponašanje opisa nije definisano jezikom, i ostavljeno je frejmvorkovima trećih lica. Na primer, biblioteka može biti napisana da prati statično pisanje:[8]
def haul(item: Haulable, *vargs: PackAnimal) -> Distance
Dekoratori
[uredi | uredi izvor]
Dekorator je bilo koji pozvani objekat Pajtona koji je korišćen za modifikovanje funkcije, metode ili definicije klase. Pajton dekoratiru su inspirisani delom od Java opisa, i imaju sličnu sintaksu; dekorator sintaksa je čisti sintatički šećer, koji koristi @
kao ključnu reč:
@viking_chorus
def menu_item():
print("spam")
je jednako
def menu_item():
print("spam")
menu_item = viking_chorus(menu_item)
Dekoratori su forma metaprogramiranja; oni unapređuju akciju funkcije ili metode koju dekorišu. Na primer, u gornjem primeru, viking_chorus
može izazvati menu_item
da se pokrene 8 puta (videti Spem skeč) za svaki put kada je pozvano:
def viking_chorus(myfunc):
def inner_func(*args, **kwargs):
for i in range(8):
myfunc(*args, **kwargs)
return inner_func
Kanonske koristi dekoratora funkcije su pravljenje metoda klasa ili statičnih metoda, dodavanje svojstava funkciji, praćenje, postavljanje preduslova i postuslova, i sinhronizacija,[9] ali mogu biti korišćeni za mnogo više osim, uključujući repno rekurzivnu eliminaciju,[10] memoizaciju i čak unapređivanje pisanja dekoratora.[11] Dekoratori mogu biti lančano povezani stavljajući nekoliko na susedne redove:
@invincible
@favorite_color("Blue")
def black_knight():
pass
je jednako
def black_knight():
pass
black_knight = invincible(favorite_color("Blue")(black_knight))
ili, korišćenjem srednjih promenljiva
def black_knight():
pass
blue_decorator = favorite_color("Blue")
decorated_by_blue = blue_decorator(black_knight)
black_knight = invincible(decorated_by_blue)
U gornjem primeru, favorite_color
dekorator fabrike uzima se za argument. Dekorator fabrika moraju vratiti dekorator, koji je zatim pozvan objektom koji će biti dekorisan kao njegov argument:
def favorite_color(color):
def decorator(func):
def wrapper():
print(color)
func()
return wrapper
return decorator
Ovo bi dekorisalo black_knight
funkciju kao što je boja, "Blue", bi zatim bila odštampana pre black_knight
funkcije. Zatvaranje osigurava da je argument boje dostupan unutrašnjosti funkcije čak i kada se vraća i izlazi van domena, što je ono što dozvoljava dekoratorima da rade.
U Pajtonu do verzije 2.6, dekoratori se primenjuju na funkcije i metode, ali ne i na klase. Dekorisanje (primer) __new__
metode može promeniti klasu, svakako.[12]
Dekoratori klasa su podržani[13] počevši sa verzijom 2.6.
Pajton dekoratori dodaju funkcionalnost funkcijama i metodama u određeno vreme. Obrazac samog dekoratora je trivijalno ugrađen u Pajton, jer je jezik osmišljen kao daktajping, ali nije tako često smatran time.[traži se izvor]
Skrivene tajne
[uredi | uredi izvor]Korisnici programskih jezika sa zakrivljenim zagradama, kao što su C ili Java, ponekad očekuju ili žele da Pajton prati konvenciju blok-graničnika. Pajton interpretator sadrži skrivenu tajnu, ili uskršnje jaje koji rezimira osećanja programera za ovaj problem. Kod from __future__ import braces
izdiže izuzetak SyntaxError: not a chance
. Modul __future__
se normalno koristi da dovede mogućnosti iz budućih verzija Pajtona.
Još jedna skrivena poruka, Zen Pajtona (rezimiranje od filozofije Pajtona), je prikazano kada se napiše import this
.
Poruka Hello world!
je ispisana kada se naredba import __hello__
iskoristi. U Pajtonu 2.7, umesto Hello world!
štampa Hello world.
..
.
Modul antigravity
je dodat u Pajtonu 2.7 i 3.0. Ubacivanjem istog otvara veb pretraživač na xkcd strip koji prikazuje duhovitu zamišljenu korist za takav modul, namenjen da demonstrira lakoću kojom Pajton moduli omogućavaju dodatnu funkcionalnost.[14]
Reference
[uredi | uredi izvor]- ^ a b v Zvanični sajt
- ^ David Mertz.
- ^ The
nonlocal
keyword was adopted by PEP 3104 - ^ "Python Style Guide". docs.python-guide.org.
- ^ EAFP, Python Glossary
- ^ Martelli, Alex (2006). Python in a Nutshell. "O'Reilly Media, Inc.". str. 134. ISBN 978-1-4493-7910-0.
- ^ Martelli 2006, str. 134.
- ^ PEP 3107 - Function Annotations | Python.org
- ^ "Python 2.4 Decorators: Reducing code duplication and consolidating knowledge".
- ^ "New Tail Recursion Decorator" Arhivirano na sajtu Wayback Machine (9. februar 2007).
- ^ "The decorator module".
- ^ David Mertz (2006-12-29).
- ^ "PEP 3129 - Class Decorators".
- ^ The referenced comic strip is xkcd #353; the module was added to the Python trunk[mrtva veza] for the 3.0 release.
Spoljašnje veze
[uredi | uredi izvor]- Python tutorial napisan od autora Pajtona, Guido van Rossum.
- Liste u Pajtonu