Пређи на садржај

Синтакса и семантика Пајтона

С Википедије, слободне енциклопедије
Синтакса и семантика Пајтона

Синтакса програмског језика Пајтон је низ правила која дефинишу како ће програм у Пајтону бити написан и интерпретиран (са рачунарске стране као и стране људског читаоца).

Филозофија дизајна

[уреди | уреди извор]

Пајтон је дизајниран да буде веома читљив језик. Има релативно неоптерећен визуелни дезен и често користи енглеске речи тамо где други језици користе знакове интерпункције. Пајтон циља ка једноставности и општост у дезену његових синтакси, осврћујући се на "Треба бити један - и само један - очигледан начин да се то уради", из "Зен Пајтона".

Ово се коси са начином рада Перл и Руби, "постоји више начина да се то уради".

Кључне речи

[уреди | уреди извор]

Пајтон има следеће кључне речи или резервисане речи; оне не могу бити коришћене као идентификатори.[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

Увлачење

[уреди | уреди извор]

Пајтон користи вајтспејс да ограничи програмске блокове, пратећи офсајд правило. Пајтон позајмљује ово својство од његовог претходника АБЦ: уместо интерпункција или кључних речи, он користи увлачење да прикаже блок у коме се одвија програмски код.

У такозваним "слободно-форматским" језицима, која користе структуру блокова из АЛГОЛ, блокови кода су раздвојени заградама ({ }) или кључним речима. У многим конвенцијама кода за ове језике, програмери конвенционо пишу код у оквиру блока, да га визуелно раздвоје од околног кода.

Замислите функцију, foo, која садржи један параметар, x, и ако је параметар 0 позваће bar и baz, у супротном позваће qux, пролазећи x, као и позвати себе рекурзивно, пролазећи x-1 као параметар. Ево су имплементације ове функције и у C и Пајтону:

foo функција у C са стилом писања К&Р:

void foo(int x)
{
    if (x == 0) {
        bar();
        baz();
    } else {
        qux(x);
        foo(x - 1);
    }
}

foo функција у Пајтону:

def foo(x):
    if x == 0:
        bar()
        baz()
    else:
        qux(x)
        foo(x - 1)

Пајтон се користи конвенцијом којом се програмери у АЛГОЛ стилу језика често користе. Штавише, у фриформ синтакси, од кад је увлачење игнорисано, добро увлачење не може бити форсирано од стране интерпретатора или компајлера. Неправилно увучен код може бити разумет са људске стране различито него што то може компајлер или интерпретатор. На пример: Неправилно увлачење у C:

for (i = 0; i < 20; ++i)
    a();
    b();
c();

Код је био намењен да позове функције a() и b() 20 пута. Али, the понављајући блок кода је само {a();}. Код позива a() 20 пута, и затим зове b() и c() само једанпут и једну и другу. Читачи овог кода могу бити преварени неправилним редоследом позивања функција b и c. Грешке увлачења у Пајтону:

def foo(x):
    if x == 0:
        bar()
        baz()
    else:
        qux(x)
    foo(x - 1)

Овде, у супротности са горе наведеним Пајтон foo примером, позивна функција foo(x - 1) бива увек извршена, резултујући се у непрекидној рекурзији. Таква врста грешке увлачења (као што је случајно брисање увлачења у задњем реду) је могуће само у програмским језицима која не обележавају блокове са јасним ознакама, као што су закривљене заграде у C. У конкретно овом примеру чак ни едитор са аутоматским увлачењем не може спречити погрешнп понашање овог Пајтон кода. Ова не намерна грешка може лако проћи у базни код без претходног примећивања од програмера. У многим другим програмским језицима ово не би било могуће (брисање крајњих блокова обележја у C би приказало компајлерску грешку) и ово чини Пајтон синтаксе много мање робусним у односу на многе друге језике.

Оба знакова, размак и таб су тренутно прихваћени као форме за увлачење у Пајтону. Пошто много алата их визуелно не разликује, мешање размака и таб-а може направити багове који захтевају напоре да се нађу. Штавише, рутине форматирања која бришу вајтспејс пример, Форум (интернет)—могу уништити синтаксу Пајтон програма, где би код програма са заградама било теже да се прочита.

Многи популарни програмски едитори рукују Пајтоновим увлачењем без проблема, понекад након омогућивања у опцијама конфигурација.

Структура података

[уреди | уреди извор]

Откако је Пајтон динамично писан језик, Пајтон вредности, не променљиве, носе тип. Ово има импликације на много аспеката на начин на који овај језик функционише.

Све вредности у Пајтону носе референце према објектима, и ове референце такође пролазе у функције; функција не може да промени вредност променљиве референце у позивној функцији (не сасвим, погледајте испод). Неки људи (укључујући Гвидо ван Росум самог) су звали ову параметарно-пролазну шему "Позвати по референци објекта." Референца објекта значи име, и пролазна референца је "алиас", на пример копија референце на исти објекат, баш као и у C/C++. Вредност објекта може бити промењена у позивној функцији са "алиас", на пример:

>>> alist = ['a', 'b', 'c']
>>> def myfunc(al):
... al.append('x')
... print al
...
>>> myfunc(alist)
['a', 'b', 'c', 'x']
>>> alist
['a', 'b', 'c', 'x']

Функција "myfunc" је променила вредност "alist" са формалним аргументом "al", који је алиас од "alist". Али, било који покушај промене самог алиаса не би имало било какав ефекат на оригинални објекат. У Пајтону, не-најдубље-локално и не-декларисано-глобално доступни називи су сви "алиаси".

Поред динамично писаних језика, Пајтон је осредње провераван у писању. Имплицитна конверзија је дефинисана за нумеричке типове (као и за булеан), тако да особа може валидно умножити комплексан број са дугим целим бројем (на пример) без експлицитног кастинга. Али, не постоји имплицитна конверзија између (на пример) бројева и стрингова; стринг је неважећи аргумент математичкој функцији која очекује број.

Типови база

[уреди | уреди извор]

Пајтон има широк опсег општих типова података. Поред конвенционалних целих бројева и децималне аритметике, он провидно подржава it аритметику арбитарне прецизности, комплексни бројеви, и бројеве у децималном запису.

Пајтон подржава широк спектар стринг операција. Стрингови у Пајтону су непроменљиви, тако да стринг операција као што је субституција карактера, да у другим програмским језицима може променити стринг у месту, враћа нови стринг у Пајтону.

Типови прикупљања

[уреди | уреди извор]

Један од корисних аспеката Пајтона је концепт прикупљања типова. Генерално, колекција је објекат који садржи друге објекте на начин који је лако референциран или индексован. Колекције долазе у два основна облика: секвенце и мапирање.

Поређани секвенциони типови су листе, торке, и стрингови. Све секвенце су индексиране по позицији (од 0 до дужине - 1) и сви сем стрингова могу садржати било који тип објекта, укључујући више типова у истој секвенци. Оба стринга и туплеа су непроменљиви, чинећи их савршеним кандидатима за кључеве речника (погледајте испод) у месту.

Мапирање, у другу руку, су непоређани типови имплементирани у форми речника чија "мапа" је скуп непроменљивих кључева одговарајућим елементима (скоро као математичка функција). На пример, особа може дефинисати речник да садржи стринг "toast" мапиран на број 42 или обрнуто. Кључеви у речнику морају бити непроменљивог Пајтон типа, као што је то integer или стринг, зато што су имплементирани преко хеш функције. Ово много убрзава претрагу, али захтева да се кључеви не мењају (што такође резултира лошом расподелом у речнику).

Речници су такође центар унутрашњости језика јер се ослањају на језгро свих Пајтон објеката и класа: мапирање између променљивих назива (стрингова) и вредности чија имена референци су складиштени као речници (погледајте систем објеката). Пошто су ови речници директно доступни (преко својства објекта __dict__), метапрограмирање је једноставан и природан процес у Пајтону.

Скуп скупљајућег типа је додат у језгро језика у верзији 2.4. Сет је неиндексована, неуређена колекција која не садржи дупликате, и имплементира set theoretic операције као што су union, пресеци, difference, symmetric difference, и подскуп тестирање. Постоје два типа сетова: set и frozenset, једина разлика је та што је set променљив а frozenset непроменљив. Елементи у сету морају бити у могућности за хешовање и да буду непроменљиви. Тако да, на пример, frozenset може бити елемент регуларног set где обрнуто није могуће.

Пајтон такође пружа широку колекцију манипулативних могућности као што је уграђено проверавање садржаја и протокол генеричног понављања.

Систем објекта

[уреди | уреди извор]

У Пајтону, све је објекат, чак и класе. Класе, као и објекти, имају класе, која су позната као њихова метакласа. Пајтон такође подржава вишеструко наследство и миксинс.

Језик подржава широку интроспекцију типова и класа. Типови могу бити читани и упоређивани—типови су инстанце type. Својства објекта могу бити претворена у речнике.

Оператори могу бити преоптерећени у Пајтону дефинисањем специјалног члана функција—на пример, дефинисање __add__ на класу омогућава особу да користи + оператор на кориснике из те класе.

Литерали

[уреди | уреди извор]

Стрингови

[уреди | уреди извор]

Пајтон има разне облике литерала.

Нормални стринг литерали

[уреди | уреди извор]

Могу се користити обични као и двојни наводници за навођење стрингова. За разлику у Unix језицима, Перл или Перл-инспирисани језици као што су Руби или Груви, обични и двојни наводници раде идентично, на пример, не постоји стринг уметање од $foo израза. Али, уметање може бити извршено користећи % string-format оператор, као што је Перл наредба

print "I just printed $num pages to the printer $printer\n"

једнака Пајтон наредби

print("I just printed %s pages to the printer %s" % (num, printer))

Али, тренутни стандард овог начина стринг форматирања је да се користи format метода стрингова:

print("I just printed {0} pages to the printer {1}".format(num, printer))

Литерали вишелинијских стрингова

[уреди | уреди извор]

Постоје и вишелинијски стрингови, који почињу и завршавају се са редом од три обичних и двојних наводника и раде као here documents у Перл и Руби.

Обичан пример са уметањем променљивих (користећи % string-format оператор) је:

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 стрингови

[уреди | уреди извор]

Коначно, сви претходно поменути облици стрингова долазе у "raw" облицима, и веома су корисни за регуларне изразе; поредити "@-quoting" у C#. Raw стрингови су оригинално намењени за регуларне изразе. Због ограничења токенајзера, raw стрингови могу да немају косу црту.[1] Прављење raw стринга која држи Windows путању која се завршава са косом цртом захтева неки облик напора (често, користећи се косам цртама унапред уместо уназад, од кад Windows прихвата оба).

Примери укључују:

# 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.

Повезивање у ланац суседних стринг литерала

[уреди | уреди извор]

Стринг литерали појављујући се спојено и раздвојени само размаком (укључујући нове редове), су дозвољени и нагомилавани у један дужи стринг.[1] title = "One Good Turn: " \'A Natural History of the Screwdriver and the Screw' </syntaxhighlight>је једнако

title = "One Good Turn: A Natural History of the Screwdriver and the Screw"

Нумерички литерали у Пајтону су нормалног типа, на пример 0, -1, 3.4, 3.5e-8.

Пајтон има произвољну дужину целих бројева и аутоматски повећавају просторно складиште по потреби. До Пајтона верзије 3, постојале су два типа целих бројева: традиционално просторно фиксирани цели бројеви и "дугачки" цели бројеви произвољног домена. Конверзија у "дугачке" целе бројеве је рађено аутоматски по потреби, и програмер обично није морао да буде свестан ова два типа целих бројева. У новијим верзијима језика, просторно-фиксни цели бројеви су потпуно нестали.

Пајтон подржава нормалне децималне бројеве, који су направљени када се користи тачка у литералу (нпр. 1.1), када су цели број и децимални број коришћени у изразу, или као резултат неке математичке операције (дељење / оператором, или степеновање негативном компонентом).

Пајтон такође подржава комплексне бројеве. Комплексни бројеви су назначени са  J или j суфиксом, нпр. 3 + 4j.

Листе, торке, сетови, речници

[уреди | уреди извор]

Пајтон има синтаксну подршку за прављење складишних типова.

Листе (класа list) су променљиве секвенце ставки произвољних типова, и могу бити направљене или са посебном синтаксом

a_list = [1, 2, 3, "a dog"]

или користећи нормалне објекте

a_second_list = list()
a_second_list.append(4)
a_second_list.append(5)

Торке (класа tuple) су променљиве секвенце ставки произвољних типова. Постоји и посебна синтакса за прављење торки

a_tuple = 1, 2, 3, "four"

Иако су торке прављене за раздвајање ставки са зарезима, цео концепт се обично своди на побољшање читљивости кода. Празна торка се означава са (). Сетови (класа set) су променљива складишта ставки променљивих типова, без дупликата. Ставке нису поређане. Синтакса за прављење сетова се појавила у Пајтону 2.7/3.0

some_set = {0, (), False}

У ранијим верзијама Пајтона, сетови би били направљени позивањем сет класе са листом аргумената. Пајтон сетови су веома слични као математички сетови, и подржавају операције као што су пресеци and уније.

Пајтон такође има  frozenset класу за непроменљиве сетове.

Речници (класа dict) су променљиво мапирани кључеви са одговарајућим вредностима. Пајтон има посебну синтаксу за прављење речника ({key: value})

a_dictionary = {"key 1":"value 1", 2:3, 4:[]}

Синтакса речника је слична сет синтакси, разлика је у присуству колона. Празан литерал {} резултује у празном речнику уместо празном сету, који је затим направљен користећи не-литерални конструктор: set().

Оператори

[уреди | уреди извор]

Аритметика

[уреди | уреди извор]

Пајтон садржи +, -, *, /, % (конгуренцију), и ** (степеновање) операторе.

Традиционално, x / y изврашавало је целобројно дељење ако су x и y били цели бројеви (враћајући само бројеве до децимале), и враћало је децимални запис ако је бар један од њих био у таквом запису. Али, пошто је Пајтон динамично писан језик, није увек било могуће знати која операција је била изврашавана, што је доводило до багова. На пример, са

def mean(seq):
    return sum(seq) / len(seq)

Позив на mean([3.0, 4.0]) би вратило 3.5, али mean([3, 4]) би вратило 3. Ако ово није било намерно понашање, било је потребно урадити нешто попут

def mean(seq):
    return float(sum(seq)) / len(seq)

Да би се избегао овај проблем, дошло је до промене на начин на који Пајтон делилац функционише. У пајтону 2.2, нови оператор // је уведен за дељење, како за целобројне тако и за децималне аргументе. Оператор / је промењен тако да количник два целобројна броја су враћала децималан запис, али за повратну компатибилност, овакво понашање би морало бити експлицитно затражено све до Пајтона 3.0.

Оператори поређења

[уреди | уреди извор]

Обични оператори поређења као што су ==, <, >=, и тако даље, су коришћени за разне вредности. Бројеви, стрингови, секвенце, и мапирање - сви они могу бити поређени међусобом. Али, различити типови (као што су  str и int) су дефинисани да имају стални релативни редослед; ово је сматрано историјским каприцом и није дозвољен од Пајтона 3.0.

Ланчани изрази поређења као што су  a < b < c имају скоро исто значење као и у математици, за разлику од необичног смисла у C и сличним језицима. Услови су проверавани и поређивани по редоследу. Операција има краткотрајну семантику, што значи да је евалуација загарантована да престане чим пресуда постане јасна: ако је a < b false, c није никада евалуирано јер израз једноставно не може бити тачан више.

За иразе без нежељених ефеката, a < b < c је једнако a < b and b < c. Али, постоји значајна разлика када изрази имају нежељене ефекте. a < f(x) < b ће да евалуира f(x) тачно једном, док a < f(x) and f(x) < b ће да га евалуира два пута ако је вредност за a мање од f(x) и једном ако није.

Логички оператори

[уреди | уреди извор]

Пајтон 2.2 и ранији немају експлицитни булеан тип. У свим верзијама Пајтона, булеан оператори третирају нулу или празне вредности као што су "", 0, None, 0.0, [], и {} као false, док у генералном третирању не-празне, не-нуле као true. У Пајтону 2.2.1 булеан константе True и False су додате у језик (уместо као 1 и 0). Оператори бинарних поређења као што су == и > враћају True или False.

Оператори булеан and и or користе минималну евалуацију. На пример, y == 0 or x/y > 100 никада неће подићи дељење нулом изузетак. Ови оператори враћају вредност из последње евалуације, уместо True или False. Тако да изрази (4 and 5) евалуирају 5, и (4 or 5) евалуира у4.

Функционално програмирање

[уреди | уреди извор]

Као што је поменуто горе, још једна предност Пајтона је доступност стила функционално програмирање. Као што се очекује, ово чини прављење листи и осталих колекција много једноставније.

Листа схватања

[уреди | уреди извор]

Једна таква конструкција је листа схватања, која може бити написана у следећем формату:

L = [mapping-expression for element in source-list if filter-expression]

Користећи листу схватања да се израчунају првих пет степена двојке:

powers_of_two = [2**n for n in range(1, 6)]

Квиксорт алгоритам може бити написан елегантно (али неефикасно) користећи се листом схватања:

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]))

Функције прве класе

[уреди | уреди извор]

У Пајтону, функције су објекти прве класе које могу бити направљене и померане динамично.

Пајтонова ограничена подршка за анонимне функције је lambda. Пошто је доступност потпуно анонимних функција непостојеће, главна корист ламбда функција је именовање функција. Ламбде су ограничене да садрже изразе уместо наредби, иако контрола тока може бити имплементирана мање елегантно са ламбда користећи се са кратким спојем.[2]

Затварање

[уреди | уреди извор]

Пајтон има подршку за лексичко затварање од верзије 2.2. Ево примера:

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

Пајтонова синтакса, понекад може натерати програмере других језика да затварање није подржано. Обим променљиве у Пајтону је прећутно одређен обимом којом особа додељује вредности променљиве, осим ако је обим експлицитно декларисан са global или nonlocal.[3] Везивање затварања имена у неку вредност није променљиво у оквиру функције. Дато:

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)

ће дати:

a: 1
b: 2
b*: 1
b: 2

и можете видети да b, као што је видљиво из обима затварања, задржава вредност коју је имало; промењено везивање од b у оквиру функције није пропагирало вани. Заобилазница око овога је коришћење променљиве вредности, затим променити ту вредност, не везивање. На пример, листа са једним елементом.

Генератори

[уреди | уреди извор]

Уведени у Пајтону 2.2 као опциона могућност, а завршена у верзији 2.3, генератори су Пајтонов механизам за лење евалуације функције која би иначе вратила превише празног или рачунски интензивну листу.

Ово је пример лењег генерисања простих бројева:

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

Да користите ову функцију, просто је позовите:

for i in generate_primes(): # iterate over ALL primes
    if i > 100:
        break
    print(i)

Дефиниција генератора се појављује идентично као што се зове, осим кључне речи yield која се користи уместо return. Али, генератор је објекат са сталним стањем, који може рекурзивно улазити и излазити исти обим. Позивање генератора може бити извршено онда уместо листе, или друге структуре чији елементи ће бити поновљени. Када год for петља у примеру захтева следећу ставку, генератор бива позиван, који приноси следећу ставку.

Генератори не морају бити бесконачни као код примера са простим бројевима горе. Када генератор заврши, унутрашњи изузетак се издиже који назначава било које позивне контексте да нема више вредности. for петља или друго понављање се затим завршава.

Изрази генератора

[уреди | уреди извор]

Уведено у Пајтону 2.4, изрази генератору су лење евалуације једнаке листи схватања. Користећи се генератором простих бројева од малопре, можемо дефинисати лењу, али не тако неограничену колекцију.

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()

Већина меморије и времена потребно за генерисање оволико простих бројева неће бити искоришћено док се не приступи потребном елементу. Нажалост, не можете извести једноставно индексирање и пресецање генератора, али многи се користе модулима itertools или "смотај сам своју" петљама. У супротности, листа схватања је функционално једнака, али и похлепна у извођењу целокупног посла:

primes_under_million = [i for i in generate_primes(2000000) if i < 1000000]
two_thousandth_prime = primes_under_million[1999]

Листа схватања ће одмах направити велику листу (са 78498 ставки, у примеру, али пролазно правећи листу простих бројева испод два милиона), иако су никада не приступи многим елементима. Генератор схватања је више шкрто.

Речник и сет схватања

[уреди | уреди извор]

Док су листе и генератори имали схватања/изразе, у Пајтону верзијама старијим од 2.7 друга уграђена колекциона типа Пајтона (dicts и sets) су морала бити уведена у коришћење листи и генератора:

>>> dict((n, n*n) for n in range(5))
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

Пајтон 2.7 и 3.0 спајају све колекционе типове уводећи dict и set схватања, слично листи схватања:

>>> [ 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}

Пајтон подржава многобројне програмске технике за објекте. Дозвољава полиморфозу, и то не само у  оквиру класе хијерархије, већ и писање дак-тајпингом. Било који објекат може бити коришћен за било који тип, и радиће све док има правилне методе и атрибуте. Све у Пајтону је објекат, укључујући класе, функције, бројеве и модуле. Пајтон такође има подршку за метакласе, напредну алатку намењену за унапређивање функционалности класа. Природно, наследство, укључујући вишеструко наследство, је подржано. Има ограничену подршку за приватне променљиве користећи се name манглингом. Погледајте "Класе" одељак овог упутства за детаље. Многи корисници Пајтона немају потребу за приватне променљиве. Слоган "Сви смо овде одговорни корисници" је коришћен да се опише овај став.[4] Неки сматрају скривање информација "непајтонски", у коме се предлаже да класа у питању садржи не естетски привлачне интервале. Какогод, најјачи аргумент за менглинг имена је превенција непредвидивог сламљања програма: уводећи нову јавну променљиву у суперкласи може сломити субкласе ако не користе "приватне" променљиве.

Из упутства: Као што је тачно за модуле, класе у Пајтону не стављају апсолутну препреку између дефиниције и корисника, већ се ослањају на учтивост корисника да не "пробије у дефиницију."

У верзији Пајтона 2.2, "нови стил" класа су уведени. Са новим стилом класа, објекти и типови су уједињени, дозвољавајући субкласовање. Чак и потпуно нови типови могу бити дефинисани, завршавајући поручено понашање за infix операторе. Ово дозвољава да се многе радикалне ствари ураде синтатички у Пајтону. Нова метода поредка резолуције за вишеструка наследства су такође уведена у Пајтону 2.3. Такође је могуће покретати ручно поручен код док се приступа или подешава атрибутима, детаљи ових техника су се мењали током Пајтон верзија.

With наредбе

[уреди | уреди извор]

Наредбе "with" раде са изворима[1]. Једна функција је позвана приликом уласка у домен и још једна приликом изласка. Ово онемогућава заборављање на брисање извора и такође ради са више компликованим ситуацијама као што су изузеци.

Својства

[уреди | уреди извор]

Својства дозвољавају специфично дефинисане методе да буду позване на пример објекта користећи се истом синтаксом као и за приступ атрибуту. Пример класе која дефинише нека својства је:

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

Дескриптори

[уреди | уреди извор]

Класа која дефинише једну или више специјалних метода  __get__(self,instance,owner), __set__(self,instance,value), __delete__(self,instance) могу бити коришћени као дескриптори. Прављење примера дескриптора као члана друге класе чини пример својством друге класе.

Класе и статичне методе

[уреди | уреди извор]

Пајтон дозвољава прављење метода класа и статичних метода коришћењем @classmethod и @staticmethod декораторима. Први аргумент методе класе је објекат класе уместо само-референтности на пример. Статична метода нема специјалан први аргумент. Нити пример, ни класа објекта не пролази у статичну методу.

Пајтон подржава (и вишеструко се користи) ослањањем на изузетке за тестирање грешака и осталих непредвидивих догађаја у програму. Заиста, могуће је заклопити изузетак изазван синтаксном грешком.

Стил Пајтона позива коришћење изузетака када год постоје услови за појављивање грешака. Прече од тестирања приступа фајлу или извору пре него што се заправо искористи, конвенционо је у Пајтону да се само настави и проба да се искористи, хватајући изузетке ако је приступ одбијен.

Изузеци су често коришћени као алтернатива if-блоку, посебно у нитним ситуацијама. Често позван мото је EAFP, или "It is Easier to Ask for Forgiveness than Permission,"[5] који је приписан Грејс Хопер.[6] У првом примеру кода, постоји експлицитна провера за атрибуте (нпр. "пита за дозволу"):

if hasattr(spam, 'eggs'):
    ham = spam.eggs
else:
    handle_error()

Други пример прати EAFP начин:

try:
    ham = spam.eggs
except AttributeError:
    handle_error()

Ова два примера кода имају исти ефекат, где нема разлике у перформансама. Када spam има својство eggs, EAFP пример ће радити много брже. Када spam нема својство eggs ("посебан" пример), EAFP пример ће радити спорије. Пајтон профајлер може бити коришћено у посебним случајевима да се измери перформанса карактеристика. Ако су посебни примери ретки, онда EAFP верзија ће имати супериорну перформансу у односу на алтернативу. Такоже, заобилази целокупну класу time-of-check-to-time-of-use (TOCTTOU) раљивости, осталих ретких случајева,[7] и компатибилни су са duck typing-ом. Лоше стране EAFP су да може бити коришћен само са наредбама; изузетак не може бити ухваћен у генератору израза, листи разумевања, или ламбда функцији.

Коментари и докстрингови

[уреди | уреди извор]

Пајтон има два начина да опише код у Пајтону. Један је коришћењем коментара да се назначе који делови кода ради шта. Коментари у једном реду почињу са знаком хештег ("#") и завршавају се на крају истог реда. Коментари који имају више редова се пишу коришћењем вишелинијских стрингова (са """ на сваком крају) који није коришћен у задатку или на други начин евалуиран, али стоји између других наредби.

Коментарисање дела кода:

def getline():
    return sys.stdin.readline()       # Get one line and return it

Коментарисање дела кода у више редова:

def getline():
    return sys.stdin.readline()    """this function
                                      gets one line
                                      and returns it"""

Докстрингови (документациони стрингови), су стрингови који се налазе самостално без задатка као првонамењени ред у оквиру модула, класе, методе или функције, аутоматски постављајући свој садржај као својство именовано са __doc__, који је намењен за складиштење описа сврхе објекта која је читљива од стране корисника, као и понашање и начин коришћења. Уграђена help функција генерише свој излаз из __doc__ својстава. Такви стрингови могу бити раздвојени са " или ' за једноредне стрингове, или вишередно ако се користи """ или ''' Какогод, стил упутства за језик каже да троструки наводници (""") су преферирани и за јдноредне и вишередне докстрингове. Једноредни докстринг:

def getline():
    """Get one line from stdin and return it."""
    return sys.stdin.readline()

Вишередни докстринг:

def getline():
    """Get one line
       from stdin
       and return it."""
    return sys.stdin.readline()

Докстрингови могу бити велики колико то програмер жели и да садржи размаке између редова. У супротности са коментарима, докстрингови су по себи објекти Пајтона и део су интерпретираног кода који Пајтон покреће. То значи да покренут програм може повратити своје докстрингове и да манипулиште тим информацијама. Али нормално коришћење је давање осталим програмерима информације како позвати објекат који се појављује у докстрингу.

Постоје доступне алатке које могу извадити докстринг да генерише АПИ документацију из кода. Докстринг документација такође може бити приступана из интерпретатора са help() функцијом, или из љуске са пајдок командом pydoc.

Стандард модула doctest се користи интеракцијама копираним из сесија љуске Пајтона у докстринговима, да се праве тестови.

Описи функција

[уреди | уреди извор]

Описи функција су дефинисани у PEP 3107. Они дозвољавају причвршћивање датотека на аргументе и повратку резултата од функције. Понашање описа није дефинисано језиком, и остављено је фрејмворковима трећих лица. На пример, библиотека може бити написана да прати статично писање:[8]

def haul(item: Haulable, *vargs: PackAnimal) -> Distance

Декоратори

[уреди | уреди извор]

Декоратор је било који позвани објекат Пајтона који је коришћен за модификовање функције, методе или дефиниције класе. Пајтон декоратиру су инспирисани делом од Java описа, и имају сличну синтаксу; декоратор синтакса је чисти синтатички шећер, који користи @ као кључну реч:

@viking_chorus
def menu_item():
    print("spam")

је једнако

def menu_item():
    print("spam")
menu_item = viking_chorus(menu_item)

Декоратори су форма метапрограмирања; они унапређују акцију функције или методе коју декоришу. На пример, у горњем примеру, viking_chorus може изазвати menu_item да се покрене 8 пута (видети Спем скеч) за сваки пут када је позвано:

def viking_chorus(myfunc):
    def inner_func(*args, **kwargs):
        for i in range(8):
            myfunc(*args, **kwargs)
    return inner_func

Канонске користи декоратора функције су прављење метода класа или статичних метода, додавање својстава функцији, праћење, постављање предуслова и постуслова, и синхронизација,[9] али могу бити коришћени за много више осим, укључујући репно рекурзивну елиминацију,[10] мемоизацију и чак унапређивање писања декоратора.[11] Декоратори могу бити ланчано повезани стављајући неколико на суседне редове:

@invincible
@favorite_color("Blue")
def black_knight():
    pass

је једнако

def black_knight():
    pass
black_knight = invincible(favorite_color("Blue")(black_knight))

или, коришћењем средњих променљива

def black_knight():
    pass
blue_decorator = favorite_color("Blue")
decorated_by_blue = blue_decorator(black_knight)
black_knight = invincible(decorated_by_blue)

У горњем примеру, favorite_color декоратор фабрике узима се за аргумент. Декоратор фабрика морају вратити декоратор, који је затим позван објектом који ће бити декорисан као његов аргумент:

def favorite_color(color):
    def decorator(func):
        def wrapper():
            print(color)
            func()
        return wrapper
    return decorator

Ово би декорисало black_knight функцију као што је боја, "Blue", би затим била одштампана пре black_knight функције. Затварање осигурава да је аргумент боје доступан унутрашњости функције чак и када се враћа и излази ван домена, што је оно што дозвољава декораторима да раде.

У Пајтону до верзије 2.6, декоратори се примењују на функције и методе, али не и на класе. Декорисање (пример) __new__ методе може променити класу, свакако.[12] Декоратори класа су подржани[13] почевши са верзијом 2.6.

Пајтон декоратори додају функционалност функцијама и методама у одређено време. Образац самог декоратора је тривијално уграђен у Пајтон, јер је језик осмишљен као дактајпинг, али није тако често сматран тиме.[тражи се извор]

Скривене тајне

[уреди | уреди извор]

Корисници програмских језика са закривљеним заградама, као што су C или Јава, понекад очекују или желе да Пајтон прати конвенцију блок-граничника. Пајтон интерпретатор садржи скривену тајну, или ускршње јаје који резимира осећања програмера за овај проблем. Код from __future__ import braces издиже изузетак SyntaxError: not a chance. Модул __future__ се нормално користи да доведе могућности из будућих верзија Пајтона.

Још једна скривена порука, Зен Пајтона (резимирање од филозофије Пајтона), је приказано када се напише import this.

Порука Hello world! је исписана када се наредба import __hello__ искористи. У Пајтону 2.7, уместо Hello world! штампа Hello world....

Модул antigravity је додат у Пајтону 2.7 и 3.0. Убацивањем истог отвара веб претраживач на xkcd стрип који приказује духовиту замишљену корист за такав модул, намењен да демонстрира лакоћу којом Пајтон модули омогућавају додатну функционалност.[14]

Референце

[уреди | уреди извор]
  1. ^ а б в Званични сајт
  2. ^ David Mertz.
  3. ^ The nonlocal keyword was adopted by PEP 3104
  4. ^ "Python Style Guide". docs.python-guide.org.
  5. ^ EAFP, Python Glossary
  6. ^ Martelli, Alex (2006). Python in a Nutshell. "O'Reilly Media, Inc.". стр. 134. ISBN 978-1-4493-7910-0. 
  7. ^ Martelli 2006, стр. 134.
  8. ^ PEP 3107 - Function Annotations | Python.org
  9. ^ "Python 2.4 Decorators: Reducing code duplication and consolidating knowledge".
  10. ^ "New Tail Recursion Decorator" Архивирано на сајту Wayback Machine (9. фебруар 2007).
  11. ^ "The decorator module".
  12. ^ David Mertz (2006-12-29).
  13. ^ "PEP 3129 - Class Decorators".
  14. ^ The referenced comic strip is xkcd #353; the module was added to the Python trunk[мртва веза] for the 3.0 release.

Спољашње везе

[уреди | уреди извор]