Підручник мови Python/Контрольні структури: відмінності між версіями
Вилучено вміст Додано вміст
< замінено на < |
м <source> -> <syntaxhighlight> (phab:T237267) |
||
Рядок 4:
Чи не найвідомішим твердженням є <code>if</code>. Приклад:
<
>>> x = int(raw_input("Прошу ввести ціле число: "))
>>> if x < 0:
Рядок 16:
... print 'Більше'
...
</syntaxhighlight>
Ця конструкція може мати нуль або більше частин <code>elif</code>,
Рядок 29:
Оператор <code>for</code> у Пайтоні трохи відрізняється від того, до якого ви могли звикнути, використовуючи C або Pascal. Замість постійного перебору чисел арифметичної прогресії (як у Pascal) чи надання користувачеві можливості визначати як крок перебору (ітерації), так і кінцеву умову (як у C), оператор <code>for</code> у мові Пайтон перебирає члени будь-якої послідовності (списку чи рядка) у порядку їхнього в ній розташування. Наприклад:
<
>>> # Довжини рядків:
... a = ['кіт', 'вікно', 'жбурляти']
Рядок 38:
вікно 5
жбурляти 8
</syntaxhighlight>
Модифікація членів послідовності під час перебору небезпечна (це, власне, може трапитися лише зі змінюваними типами, як, скажімо, списки). Якщо потріно змінити список, що в даний час перебирається, (наприклад, подвоїти певні члени), то для цього слід перебирати копію списку. Синтаксис зрізів дозволяє це зручно робити:
<
>>> for x in a[:]: # зробити копію цілого списку за допомогою зрізів
... if len(x) > 6: a.insert(0, x)
Рядок 48:
>>> a
['жбурляти', 'кіт', 'вікно', 'жбурляти']
</syntaxhighlight>
=== Функція <code>range()</code> ===
Якщо потрібно перебрати послідовність чисел, то тут стане в нагоді стандартна функція <code>range()</code>. Вона створює списки, що містять арифметичні прогресії:
<
>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
</syntaxhighlight>
Задане останнє значення ніколи не є частиною створеного списку: <code>range(10)</code> створює список із десяти елементів, які відповідають індексам послідовності довжиною 10 елементів. Можливо також задати початок списку іншим числом та вказати інший крок (навіть від'ємний):
<
>>> range(5, 10)
[5, 6, 7, 8, 9]
Рядок 67:
>>> range(-10, -100, -30)
[-10, -40, -70]
</syntaxhighlight>
Щоб перебрати індекси послідовності, слід використовувати функції
<code>range()</code> та <code>len()</code> таким чином:
<
>>> a = ['У', 'Марічки', 'є', 'ягнятко']
>>> for i in range(len(a)):
Рядок 81:
2 є
3 ягнятко
</syntaxhighlight>
=== Оператор <code>break</code> та <code>continue</code>; конструкція <code>else</code> у циклах ===
Рядок 90:
Циклічні оператори можуть також мати конструкцію <code>else</code>, яка виконується, коли цикл завершується виснаженням списку (для <code>for</code>) або коли умова перестає бути істинною (для <code>while</code>), але не тоді, коли цикл закінчується примусово, за допомогою <code>break</code>. Наведений нижче код показує, як це діє на прикладі пошуку простих чисел:
<
>>> for n in range(2, 10):
... for x in range(2, n):
Рядок 108:
8 дорівнює 2 * 4
9 дорівнює 3 * 3
</syntaxhighlight>
=== Оператор <code>pass</code> ===
Рядок 114:
потребує жодної дії. Наприклад:
<
>>> while True:
... pass # Очікування сигналу переривання з клавіатури
...
</syntaxhighlight>
=== Визначення функцій ===
Створімо функцію, що виводить числа Фібоначчі до певної межі:
<
>>> def fib(n): # вивести числа Фібоначчі до n
... """Вивести числа Фібоначчі до n."""
Рядок 134:
... fib(2000)
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597
</syntaxhighlight>
Ключове слово <code>def</code> вводить ''визначення'' (definition) функції. За ним повинна бути назва функції та оточений дужками список формальних параметрів. Інструкції які утворюють тіло функції починаються з наступного рядка і повинні бути виділені пробілами. Першим, але необов'язковим, рядком функції може бути символьна константа, яка коротко описує функцію. Її називають рядком документації.
Рядок 146:
Визначення функції додає назву функції до поточного простору імен. Значення назви функції належить до типу, який ідентифікується інтерпретатором як задана користувачем функція. Це значення може присвоюватися іншій змінній, що потім теж може використовуватися як функція. Тут показано, як діє загальний механізм перейменування:
<
>>> fib
<function object at 10042ed0>
Рядок 152:
>>> f(100)
1 1 2 3 5 8 13 21 34 55 89
</syntaxhighlight>
Можливо хтось скаже що <code>fib</code> — не функція, а процедура. У Пайтоні, як і в C, процедури — це функції, що не повертають жодного значення. Власне, з технічної точки зору, процедури таки повертають певне значення, хоча й досить нецікаве. Це значення <code>None</code>. Зазвичай, це значення не виводиться інтерпретатором, якщо це єдине можливе значення для виводу. Але якщо дійсно хочеться його побачити, його потрібно роздрукувати явно:
<
>>> print fib(0)
None
</syntaxhighlight>
Створення функції, що повертає список чисел Фібоначчі замість виведення їх на друк, досить просте:
<
>>> def fib2(n): # повертає числа Фібоначчі до n
... """Повертає список чисел Фібоначчі до n"""
Рядок 176:
>>> f100 # вивід результату
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
</syntaxhighlight>
Цей приклад також демонструє кілька нових властивостей мови Пайтон:
Рядок 189:
Найкорисніший спосіб — це визначити типове значення для одного чи кількох аргументів. Це створює можливість виклику функції з меншою кількістю аргументів, аніж задано у визначенні функції. Наприклад:
<
def ask_ok(prompt, retries=4, complaint='Так чи ні, будь-ласка!'):
while True:
Рядок 198:
if retries < 0: raise IOError, 'затятий користувач'
print complaint
</syntaxhighlight>
Ця функція може викликатися як <code>ask_ok('Справді закрити програму?')</code> чи як <code>ask_ok('Переписати файли?', 2)</code>.
Рядок 206:
Стандартні значення обчислюються в момент задання функції відповідно до ''визначаючого'' контенсту, тому:
<
i = 5
Рядок 214:
i = 6
f()
</syntaxhighlight>
виведе <code>5</code>.
Рядок 224:
викликах:
<
def f(a, L=[]):
L.append(a)
Рядок 232:
print f(2)
print f(3)
</syntaxhighlight>
Це виведе:
<
[1]
[1, 2]
[1, 2, 3]
</syntaxhighlight>
Якщо ви не хочете, щоб стандартне значення було спільним для всіх наступних викликів, то можна створити функцію на зразок:
<
def f(a, L=None):
if L is None:
Рядок 250:
L.append(a)
return L
</syntaxhighlight>
Рядок 256:
Функції можуть також викликатися за допомогою ''ключових аргументів'' у вигляді "''ключ = значення''". Наприклад, ця функція:
<
def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'):
print "-- This parrot wouldn't", action,
Рядок 262:
print "-- Lovely plumage, the", type
print "-- It's", state, "!"
</syntaxhighlight>
може викликатися у будь-який вказаний нижче спосіб:
<
parrot(action = 'VOOOOOM', voltage = 1000000)
parrot('a thousand', state = 'pushing up the daisies')
parrot('a million', 'bereft of life', 'jump')
</syntaxhighlight>
але такі виклики неправильні:
<
parrot() # пропущено обов'язковий аргумент
parrot(voltage=5.0, 'dead') # неключовий аргумент передається після ключового
parrot(110, voltage=220) # два значення для одного аргумента
parrot(actor='John Cleese') # невідомий ключ
</syntaxhighlight>
Взагалі в списку аргументів позиційні аргументи повинні бути розташовані перед ключовими, при цьому ключі повинні бути вибрані з формальних назв параметрів. Чи задані для цього параметра стандартні значення — не важливо. Жоден аргумент не може отримувати значення більш, ніж один раз — формальні назви параметрів, що відповідають позиційним аргументам не можуть використовуватися як ключові слова під час того самого виклику. Ось приклад того, коли помилка відбувається саме через це обмеження:
<
>>> def function(a):
... pass
Рядок 291:
File "<stdin>", line 1, in ?
TypeError: function() got multiple values for keyword argument 'a'
</syntaxhighlight>
Якщо останній формальний параметр задано у формі ''**назва'', то він отримує ''словник'', що складається з аргументів, чиї ключі відповідають формальним параметрам. Він може сполучатися з формальним параметром у формі ''*назва'' (описаний в наступному підрозділі), який отримує кортеж, що складається з позиційних аргументів, не включених у список формальних пареметрів (аргумент ''*назва'' повинен передувати аргументу ''**назва''). Наприклад, функцію, задану таким чином:
<
def cheeseshop(kind, *arguments, **keywords):
print "-- Do you have any", kind, '?'
Рядок 304:
keys.sort()
for kw in keys: print kw, ':', keywords[kw]
</syntaxhighlight>
можна викликати отак:
<
cheeseshop('Limburger', "It's very runny, sir.",
"It's really very, VERY runny, sir.",
Рядок 314:
shopkeeper='Michael Palin',
sketch='Cheese Shop Sketch')
</syntaxhighlight>
Що, звичайно, виведе:
<
-- Do you have any Limburger ?
-- I'm sorry, we're all out of Limburger
Рядок 327:
shopkeeper : Michael Palin
sketch : Cheese Shop Sketch
</syntaxhighlight>
Зауважте, що метод ключових аргументів <code>sort()</code> викликано перед виведенням змісту словника <code>keywords</code>, бо інакше порядок виведення аргументів був би невизначеним.
Рядок 335:
аргументи передаються за допомогою кортежа. Нуль чи більше звичайних аргументів можуть передувати змінній кількості аргументів.
<
def fprintf(file, format, *args):
file.write(format % args)
</syntaxhighlight>
==== Розпакування списків аргументів ====
Зворотня ситуація трапляється, коли аргументи задані списком чи кортежем, але їх потрібно розпакувати для виклику функції, що потребує окремих позиційних аргументів. Наприклад, вбудована функція <code>range()</code> потребує двох окремих аргументів, що вказують на межі послідовності. Якщо вони не задані окремо, виклик функції слід писати з оператором <code>*</code>, що дозволяє розпакувати аргументи, задані списком чи кортежем:
<
>>> range(3, 6) # звичайний виклик з окремими аргументами
[3, 4, 5]
Рядок 349:
>>> range(*args) # виклик із аргументами, розпакованими зі списку
[3, 4, 5]
</syntaxhighlight>
==== Лямбда-функції ====
За популярною вимогою до Пайтона було додано кілька нових властивостей, типових для функціональних мов програмування та мови Lisp. Ключове слово <code>lambda</code> дозволяє створювати невеличкі анонімні функції. Ось, наприклад, функція, що повертає суму двох своїх аргументів: "<code>lambda a, b: a+b</code>". Лямбда-функції можуть стати в нагоді, коли потрібні об'єкти функцій. Синтаксично вони обмежені одним єдиним виразом. Семантично вони просто синтаксичний цукор нормального визначення функції. Подібно до вкладених функцій лямбда-функції можуть посилатися на змінні із зовнішнього контексту:
<
>>> def make_incrementor(n):
... return lambda x: x + n
Рядок 363:
>>> f(1)
43
</syntaxhighlight>
==== Рядки документації ====
Рядок 392:
Ось приклад багаторядкової документації:
<
>>> def my_function():
... """Не робить нічого, лише містить документацію.
Рядок 403:
Не робить нічого, лише містить документацію.
Справді, ця функція не робить нічого.</
|