3) Основи Python. Створення скриптів та керування логікою програм

6 травня 2025 11 хвилин Автор: Lady Liberty

Хочете навчитися програмувати на Python з нуля? У цій статті ми детально розглянемо створення базових скриптів та керування ходом програми — ключові навички для новачків. Ви дізнаєтеся, як зробити файл виконуваним, як передавати аргументи в скрипт через argv, та як організувати введення інформації від користувача.

Створення базових скриптів

Якщо говорити в цілому, то скрипт – це звичайний файл. У цьому файлі зберігається послідовність команд, які необхідно виконати. Почнемо із базового скрипту. Виведемо на стандартний потік виведення кілька рядків.

Для цього потрібно створити файл access_template.py з таким вмістом:

access_template = ['switchport mode access',
                   'switchport access vlan {}',
                   'switchport nonegotiate',
                   'spanning-tree portfast',
                   'spanning-tree bpduguard enable']

print('\n'.join(access_template).format(5))

Спочатку елементи списку об’єднуються в рядок, який розділений символом \n, а в рядок є номер VLAN, використовуючи форматування рядків. Після цього потрібно зберегти файл і перейти до командного рядка.

Так виглядає виконання скрипту:

$ python access_template.py
switchport mode access
switchport access vlan 5
switchport nonegotiate
spanning-tree portfast
spanning-tree bpduguard enable

Ставити розширення .pyу файлу необов’язково, але, якщо ви використовуєте Windows, це бажано робити, оскільки Windows використовує розширення файлу визначення того, як обробляти файл.

В курсі всі скрипти, які створюватимуться, використовують розширення .py. Можна сказати, що це гарний тон – створювати скрипти Python з таким розширенням.

Виконуваний файл

Для того, щоб файл був виконуваним, і не потрібно було щоразу писати python перед викликом файлу, потрібно:

  • зробити файл виконуваним (для Linux)

  • у першому рядку файлу має бути рядок або, залежно від того, яка версія Python використовується за умовчанням#!/usr/bin/env python#!/usr/bin/env python3

Приклад файлу access_template_exec.py:

#!/usr/bin/env python3

access_template = ['switchport mode access',
                   'switchport access vlan {}',
                   'switchport nonegotiate',
                   'spanning-tree portfast',
                   'spanning-tree bpduguard enable']

print('\n'.join(access_template).format(5))

Після цього:

chmod +x access_template_exec.py

Тепер можна викликати файл таким чином:

$ ./access_template_exec.py

Передача аргументів скрипту (argv)

Дуже часто скрипт вирішує якусь загальну задачу. Наприклад, скрипт обробляє якось файл конфігурації. Набагато краще буде передавати ім’я файлу як аргумент скрипту, а потім використовувати вже вказаний файл. Модуль sys дозволяє працювати з аргументами скрипта за допомогою argv.

Приклад access_template_argv.py:

from sys import argv

interface = argv[1]
vlan = argv[2]

access_template = ['switchport mode access',
                   'switchport access vlan {}',
                   'switchport nonegotiate',
                   'spanning-tree portfast',
                   'spanning-tree bpduguard enable']

print('interface {}'.format(interface))
print('\n'.join(access_template).format(vlan))

Перевірка роботи скрипту:

$ python access_template_argv.py Gi0/7 4
interface Gi0/7
switchport mode access
switchport access vlan 4
switchport nonegotiate
spanning-tree portfast
spanning-tree bpduguard enable

Аргументи, які були передані скрипту, підставляються як значення шаблону.

Тут треба пояснити кілька моментів:

  • argv – це список

  • всі аргументи знаходяться у списку у вигляді рядків

  • argv містить не лише аргументи, які передали скрипту, але й назву самого скрипту

У цьому випадку у списку argv знаходяться такі елементи:

['access_template_argv.py', 'Gi0/7', '4']

Спочатку йде ім’я самого скрипта, потім аргументи в тому ж порядку.

Введення інформації користувачем

Іноді потрібно отримати інформацію від користувача, наприклад, запросити пароль.

Для отримання інформації від користувача використовується функція input:

In [1]: print(input('Твой любимый протокол маршрутизации? '))
Твій улюблений протокол маршрутизації? OSPF
OSPF

В даному випадку інформація відразу виводиться користувачеві, але крім цього інформація, яку ввів користувач, може бути збережена в якусь змінну і може використовуватися далі в скрипті.

In [2]: protocol = input('Твій улюблений протокол маршрутизації? ')
Твій улюблений протокол маршрутизації? OSPF

In [3]: print(protocol)
OSPF

У дужках зазвичай пишеться якесь питання, яке уточнює, яку інформацію потрібно запровадити.

Запит інформації зі скрипту (файл access_template_input.py):

interface = input('Enter interface type and number: ')
vlan = input('Enter VLAN number: ')

access_template = ['switchport mode access',
                   'switchport access vlan {}',
                   'switchport nonegotiate',
                   'spanning-tree portfast',
                   'spanning-tree bpduguard enable']

print('\n' + '-' * 30)
print('interface {}'.format(interface))
print('\n'.join(access_template).format(vlan))

У перших двох рядках запитується інформація користувача. Рядок використовується для того, щоб візуально відокремити запит інформації від виводу.print('\n' + '-' * 30)

Виконання скрипту:

$ python access_template_input.py
Enter interface type and number: Gi0/3
Enter VLAN number: 55

------------------------------
interface Gi0/3
switchport mode access
switchport access vlan 55
switchport nonegotiate
spanning-tree portfast
spanning-tree bpduguard enable

Контроль ходу програми

Досі весь код виконувався послідовно – усі рядки скрипту виконувались в тому порядку, в якому вони записані у файлі. У цьому розділі розглядаються можливості Python в керуванні ходом програми:

  • відгалуження в ході програми за допомогою конструкціїif/elif/else

  • повторення дій у циклі за допомогою конструкцій forтаwhile

  • обробка помилок за допомогою конструкціїtry/except

if/elif/else

Конструкція if/elif/elseдозволяє робити відгалуження під час програми. Програма йде у гілку під час виконання певної умови.

У цій конструкції тільки if є обов’язковим, elif та else опціональні:

  • Перевірка if завжди йде першою.

  • Після оператора if має бути якась умова: якщо ця умова виконується (повертає True), то дії в блоці if виконуються.

  • За допомогою elif можна зробити кілька розгалужень, тобто перевіряти вхідні дані на різні умови.

  • Блок elif це той же if, але тільки наступна перевірка. Грубо кажучи, це «а якщо…»

  • Блоків elif може бути багато.

  • Блок else виконується у тому випадку, якщо жодна з умов if або elif не була істинною.

Приклад конструкції:

In [1]: a = 9

In [2]: if a == 10:
   ...:     print('a равно 10')
   ...: elif a < 10:
   ...:     print('a меньше 10')
   ...: else:
   ...:     print('a больше 10')
   ...:
a менше 10

Умови

Конструкція if побудована на умовах: після if та elif завжди пишеться умова. Блоки if/elif виконуються лише коли умова повертає True, тому перше з чим треба розібратися – це що є істинним, а що є хибним у Python.

True та False

У Python, крім очевидних значень True і False, решті всіх об’єктів також відповідає помилкове або справжнє значення.

Справжнє значення:

  • будь-яке ненульове число

  • будь-який непустий рядок

  • будь-який непустий об’єкт

Хибне значення:

  • 0

  • None

  • порожній рядок

  • порожній об’єкт

Наприклад, так як порожній список це помилкове значення, перевірити, чи порожній список, можна так:

In [12]: list_to_test = [1, 2, 3]

In [13]: if list_to_test:
   ....:     print("В списке есть объекты")
   ....:
В списку є об'єкти

Той самий результат можна було б отримати трохи інакше:

In [14]: if len(list_to_test) != 0:
   ....:     print("В списке есть объекты")
   ....:
В списку є об'єкти

Оператори

Оператори порівняння , які можуть використовуватися в умовах:

In [3]: 5 > 6
Out[3]: False

In [4]: 5 > 2
Out[4]: True

In [5]: 5 < 2
Out[5]: False

In [6]: 5 == 2
Out[6]: False

In [7]: 5 == 5
Out[7]: True

In [8]: 5 >= 5
Out[8]: True

In [9]: 5 <= 10
Out[9]: True

In [10]: 8 != 10
Out[10]: True

Зверніть увагу, що рівність перевіряється подвійним ==.

Приклад використання операторів порівняння:

In [1]: a = 9

In [2]: if a == 10:
   ...:     print('a равно 10')
   ...: elif a < 10:
   ...:     print('a меньше 10')
   ...: else:
   ...:     print('a больше 10')
   ...:
а менше 10

Оператор in

Оператор inдозволяє виконувати перевірку на наявність елемента у послідовності (наприклад, елемента у списку або підрядки у рядку):

In [8]: 'Fast' in 'FastEthernet'
Out[8]: True

In [9]: 'Gigabit' in 'FastEthernet'
Out[9]: False

In [10]: vlan = [10, 20, 30, 40]

In [11]: 10 in vlan
Out[11]: True

In [12]: 50 in vlan
Out[12]: False

При використанні словників умова in виконує перевірку за ключами словника:

In [15]: r1 = {
   ....:  'IOS': '15.4',
   ....:  'IP': '10.255.0.1',
   ....:  'hostname': 'london_r1',
   ....:  'location': '21 New Globe Walk',
   ....:  'model': '4451',
   ....:  'vendor': 'Cisco'}

In [16]: 'IOS' in r1
Out[16]: True

In [17]: '4451' in r1
Out[17]: False

Оператори and, or, not

В умовах можуть також використовуватися логічні оператори and , ornot:

In [15]: r1 = {
   ....:  'IOS': '15.4',
   ....:  'IP': '10.255.0.1',
   ....:  'hostname': 'london_r1',
   ....:  'location': '21 New Globe Walk',
   ....:  'model': '4451',
   ....:  'vendor': 'Cisco'}

In [18]: vlan = [10, 20, 30, 40]

In [19]: 'IOS' in r1 and 10 in vlan
Out[19]: True

In [20]: '4451' in r1 and 10 in vlan
Out[20]: False

In [21]: '4451' in r1 or 10 in vlan
Out[21]: True

In [22]: not '4451' in r1
Out[22]: True

In [23]: '4451' not in r1
Out[23]: True

Оператор and

У Python оператор andповертає не булеве значення, а значення одного з операндів.

Якщо обидва операнди є істиною, результатом виразу буде останнє значення:

In [24]: 'string1' and 'string2'
Out[24]: 'string2'

In [25]: 'string1' and 'string2' and 'string3'
Out[25]: 'string3'

Якщо один із операторів є брехнею, результатом виразу буде перше хибне значення:

In [26]: '' and 'string1'
Out[26]: ''

In [27]: '' and [] and 'string1'
Out[27]: ''

Оператор or

Оператор or, як і оператор and, повертає значення одного з операндів.

Оцінюючи операндів повертається перший справжній операнд:

In [28]: '' or 'string1'
Out[28]: 'string1'

In [29]: '' or [] or 'string1'
Out[29]: 'string1'

In [30]: 'string1' or 'string2'
Out[30]: 'string1'

Якщо всі значення є помилковими, повертається останнє значення:

In [31]: '' or [] or {}
Out[31]: {}

Важлива особливість роботи оператора or– операнди, які перебувають після істинного, не обчислюються:

In [33]: '' or sorted([44, 1, 67])
Out[33]: [1, 44, 67]

In [34]: '' or 'string1' or sorted([44, 1, 67])
Out[34]: 'string1'

Приклад використання конструкції if/elif/else

Приклад скрипта check_password.py, який перевіряє довжину пароля та чи є в паролі ім’я користувача:

# -*- coding: utf-8 -*-

username = input('Введіть ім'я користувача: ')
password = input('Введіть пароль: ')

if len(password) < 8:
    print('Пароль занадто короткий')
elif username in password:
    print('Пароль містить ім'я користувача')
else:
    print('Встановлено пароль для користувача {}'.format(ім'я користувача))

Перевірка скрипту:

$ python check_password.py Введіть ім’я користувача: nata Введіть пароль: nata1234 Пароль містить ім’я користувача
$ python check_password.py Введіть ім’я користувача: nata Введіть пароль: 123nata123 Пароль містить ім’я користувача
$ python check_password.py Введіть ім’я користувача: nata Введіть пароль: 1234 Надто короткий пароль
$ python check_password.py Введіть ім’я користувача: nata Введіть пароль: 123456789 Пароль для користувача nata встановлений

Тернарний вираз (Ternary expression)

Іноді зручніше використовувати тернарний оператор, ніж розгорнуту форму:

s = [1, 2, 3, 4]
result = True if len(s) > 5 else False

Цим краще не зловживати, але в простих виразах такий запис може бути корисним.

for

Дуже часто одну й ту саму дію треба виконати для набору однотипних даних. Наприклад, перетворити всі рядки у списку у верхній регістр. Для виконання таких дій у Python використовується цикл for.

Цикл for перебирає по одному елементи зазначеної послідовності та виконує дії, які вказані в блоці for для кожного елемента.

Приклади послідовностей елементів, якими може проходити цикл for:

  • рядок

  • список

  • словник

  • Функція range

  • будь-який об’єкт, що ітерується

Приклад перетворення рядків у списку у верхній регістр без циклу for:

In [1]: words = ['list', 'dict', 'tuple']

In [2]: upper_words = []

In [3]: words[0]
Out[3]: 'list'

In [4]: words[0].upper() # перетворення слова у верхній реєстр
Out[4]: 'LIST'

In [5]: upper_words.append(words[0].upper()) # перетворення та додавання в новий список

In [6]: upper_words
Out[6]: ['LIST']

In [7]: upper_words.append(words[1].upper())

In [8]: upper_words.append(words[2].upper())

In [9]: upper_words
Out[9]: ['LIST', 'DICT', 'TUPLE']

Дане рішення має кілька нюансів:

  • одну і ту ж дію треба повторювати кілька разів

  • код прив’язаний до певної кількості елементів у списку words

Ті ж дії з циклом for:

In [10]: words = ['list', 'dict', 'tuple']

In [11]: upper_words = []

In [12]: for word in words:
    ...:     upper_words.append(word.upper())
    ...:

In [13]: upper_words
Out[13]: ['LIST', 'DICT', 'TUPLE']

Вираз означає «для кожного слова у списку words виконати дії у блоці for». При цьому слово це ім’я змінної, яке кожну ітерацію циклу посилається на різні значення.for word in words: upper_words.append(word.upper()).

Цикл for може працювати з будь-якою послідовністю елементів. Наприклад, вище використовувався список та цикл перебирав елементи списку. Аналогічним чином для роботи з кортежами.

При роботі з рядками цикл for перебирає символи рядка, наприклад:

In [1]: for letter in 'Test string':
   ...:     print(letter)
   ...:
T
e
s
t

s
t
r
i
n
g

У циклі використовується змінна з іменем letter . Хоча ім’я може бути будь-яким, зручно, коли ім’я підказує, через які об’єкти проходить цикл.

Іноді у циклі необхідно використовувати послідовність чисел. У цьому випадку, найкраще використовувати функцію range

Приклад циклу for з функцією range():

In [2]: for i in range(10):
   ...:     print(f'interface FastEthernet0/{i}')
   ...:
interface FastEthernet0/0
interface FastEthernet0/1
interface FastEthernet0/2
interface FastEthernet0/3
interface FastEthernet0/4
interface FastEthernet0/5
interface FastEthernet0/6
interface FastEthernet0/7
interface FastEthernet0/8
interface FastEthernet0/9

У цьому циклі використовується range(10). Функція range генерує числа в діапазоні від нуля до вказаного числа (у даному прикладі – до 10), не включаючи його.

У цьому прикладі цикл проходить за списком VLAN, тому змінну можна назвати vlan:

In [3]: vlans = [10, 20, 30, 40, 100]
In [4]: for vlan in vlans:
   ...:     print(f'vlan {vlan}')
   ...:     print(f' name VLAN_{vlan}')
   ...:
vlan 10
 name VLAN_10
vlan 20
 name VLAN_20
vlan 30
 name VLAN_30
vlan 40
 name VLAN_40
vlan 100
 name VLAN_100

Коли цикл йде за словником, то фактично він проходить за ключами:

In [34]: r1 = {
    ...:      'ios': '15.4',
    ...:      'ip': '10.255.0.1',
    ...:      'hostname': 'london_r1',
    ...:      'location': '21 New Globe Walk',
    ...:      'model': '4451',
    ...:      'vendor': 'Cisco'}
    ...:

In [35]: for k in r1:
    ...:     print(k)
    ...:
ios
ip
hostname
location
model
vendor

Якщо потрібно виводити пари ключ-значення в циклі, можна робити так:

In [36]: for key in r1:
    ...:     print(key + ' => ' + r1[key])
    ...:
ios => 15.4
ip => 10.255.0.1
hostname => london_r1
location => 21 New Globe Walk
model => 4451
vendor => Cisco
In [36]: for key in r1:
    ...:     print(key + ' => ' + r1[key])
    ...:
ios => 15.4
ip => 10.255.0.1
hostname => london_r1
location => 21 New Globe Walk
model => 4451
vendor => Cisco

Або скористатися методом items, який дозволяє проходити в циклі відразу по парі ключ-значення:

In [37]: for key, value in r1.items():
    ...:     print(key + ' => ' + value)
    ...:
ios => 15.4
ip => 10.255.0.1
hostname => london_r1
location => 21 New Globe Walk
model => 4451
vendor => Cisco

Метод items повертає спеціальний об’єкт view, який відображає пари ключ-значення:

In [38]: r1.items()
Out[38]: dict_items([('ios', '15.4'), ('ip', '10.255.0.1'), ('hostname', 'london_r1'), ('location', '21 New Globe Walk'), ('model', '4451'), ('vendor', 'Cisco')])

Вкладені for

Цикли for можна вкладати один одного.

У цьому прикладі у списку commands зберігаються команди, які потрібно виконати для кожного з інтерфейсів у списку fast_int:

In [7]: commands = ['switchport mode access', 'spanning-tree portfast', 'spanning-tree bpduguard enable']
In [8]: fast_int = ['0/1','0/3','0/4','0/7','0/9','0/10','0/11']

In [9]: for intf in fast_int:
   ...:     print('interface FastEthernet {}'.format(intf))
   ...:     for command in commands:
   ...:         print(' {}'.format(command))
   ...:
interface FastEthernet 0/1
 switchport mode access
 spanning-tree portfast
 spanning-tree bpduguard enable
interface FastEthernet 0/3
 switchport mode access
 spanning-tree portfast
 spanning-tree bpduguard enable
interface FastEthernet 0/4
 switchport mode access
 spanning-tree portfast
 spanning-tree bpduguard enable
...

Перший цикл for проходить за інтерфейсами у списку fast_int, а другий за командами у списку commands.

Поєднання for та if

Розглянемо приклад суміщення for та if.

Файл generate_access_port_config.py:

 1 access_template = ['switchport mode access',
 2                    'switchport access vlan',
 3                    'spanning-tree portfast',
 4                    'spanning-tree bpduguard enable']
 5
 6 access = {'0/12': 10, '0/14': 11, '0/16': 17, '0/17': 150}
 7
 8 for intf, vlan in access.items():
 9     print('interface FastEthernet' + intf)
10     for command in access_template:
11         if command.endswith('access vlan'):
12             print(' {} {}'.format(command, vlan))
13         else:
14             print(' {}'.format(command))

Коментарі до коду:

  • У першому циклі for перебираються ключі та значення у вкладеному словнику access

  • Поточний ключ, на даний момент циклу, зберігається в змінній intf

  • Поточне значення, на даний момент циклу, зберігається в змінній vlan

  • Виводиться рядок interface FastEthernet з додаванням до нього номера інтерфейсу

  • У другому циклі for перебираються команди зі списку access_template

Оскільки до команди switchport access vlan треба додати номер VLAN:

  • всередині другого циклу for перевіряються команди

  • якщо команда закінчується на access vlan

  • виводиться команда, і до неї додається номер VLAN

У всіх інших випадках просто виводиться команда.

Результат виконання скрипту:

$ python generate_access_port_config.py
interface FastEthernet0/12
 switchport mode access
 switchport access vlan 10
 spanning-tree portfast
 spanning-tree bpduguard enable
interface FastEthernet0/14
 switchport mode access
 switchport access vlan 11
 spanning-tree portfast
 spanning-tree bpduguard enable
interface FastEthernet0/16
 switchport mode access
 switchport access vlan 17
 spanning-tree portfast
 spanning-tree bpduguard enable
interface FastEthernet0/17
 switchport mode access
 switchport access vlan 150
 spanning-tree portfast
 spanning-tree bpduguard enable

while

Цикл while – це ще один різновид циклу в Python.

У циклі while, як і у вираженні if, треба писати умову. Якщо умова істинна, виконуються дії всередині блоку while. При використанні циклів while необхідно звертати увагу на те, чи буде досягнуто такий стан, за якого умова циклу буде хибною.

Розглянемо простий приклад:

In [1]: a = 5

In [2]: while a > 0:
   ...:     print(a)
   ...:     a -= 1 # Эта запись равнозначна a = a - 1
   ...:
5
4
3
2
1

Спочатку створюється змінна зі значенням 5.

Потім, у циклі while зазначено умову a > 0. Тобто, поки значення а більше 0, виконуватимуться дії у тілі циклу. В даному випадку буде виводитися значення змінної а.

Крім того, в тілі циклу при кожному проходженні значення а стає на одиницю менше.

Запис може бути трохи незвичайним. Python дозволяє використовувати такий формат замість .a -= 1a = a - 1

Аналогічним чином можна писати: , , .a += 1a *= 2a /= 2

Так як значення а зменшується, цикл не буде нескінченним, і в якийсь момент вираз a> 0 стане хибним.

Наступний приклад побудований на основі прикладу про пароль з розділу про конструкцію if. За допомогою циклу while можна зробити так, що скрипт сам запитуватиме пароль заново, якщо він не відповідає вимогам.

Файл check_password_with_while.py:

# -*- coding: utf-8 -*-

username = input('Введіть ім'я користувача: ')
password = input('Введіть пароль: ')

password_correct = False

while not password_correct:
    if len(password) < 8:
        print('Пароль занадто короткий\n')
        password = input('Введіть пароль ще раз: ')
    elif username in password:
        print('Пароль містить ім'я користувача\n')
        password = input('Введіть пароль ще раз: ')
    else:
        print(f'Пароль для користувача {username} установлен')
        password_correct = True

У цьому випадку цикл while корисний, тому що він повертає скрипт знову на початок перевірок, дозволяє знову набрати пароль, але при цьому не вимагає перезапуску самого скрипта.

Тепер скрипт відпрацьовує так:

$ python check_password_with_while.py
Введіть ім'я користувача: nata
Введіть пароль: nata
Пароль занадто короткий

Введіть пароль ще раз: natanata
Пароль містить ім'я користувача

Введіть пароль ще раз: 123345345345
Пароль для користувача nata встановлений

break, continue, pass

Python має кілька операторів, які дозволяють змінювати поведінку циклів за замовчуванням.

Оператор break

Оператор breakдозволяє достроково перервати цикл:

  • break перериває поточний цикл і продовжує виконання наступних виразів

  • якщо використовується кілька вкладених циклів, break перериває внутрішній цикл і продовжує виконувати вирази, що йдуть за блоком * break може використовуватися в циклах for і while

Приклад із циклом for:

In [1]: for num in range(10):
   ...:     if num < 7:
   ...:         print(num)
   ...:     else:
   ...:         break
   ...:
0
1
2
3
4
5
6

Приклад із циклом while:

In [2]: i = 0
In [3]: while i < 10:
   ...:     if i == 5:
   ...:         break
   ...:     else:
   ...:         print(i)
   ...:         i += 1
   ...:
0
1
2
3
4

Використання break у прикладі із запитом пароля (файл check_password_with_while_break.py):

username = input('Введіть ім'я користувача: ')
password = input('Введіть пароль: ')

while True:
    if len(password) < 8:
        print('Пароль занадто короткий\n')
    elif username in password:
        print('Пароль містить ім'я користувача\n')
    else:
        print('Пароль для користувача{} установлен'.format(ім'я користувача))
        # завершает цикл while
        break
    password = input('Введіть пароль ще раз: ')

Тепер можна не повторювати рядок у кожному відгалуженні, достатньо перенести його в кінець циклу.password = input('Введите пароль еще раз: ')

І як тільки буде введено правильний пароль, break виведе програму з циклу while.

Оператор continue

Оператор continue повертає керування на початок циклу. Тобто, continue дозволяє «перестрибнути» вирази в циклі, що залишилися, і перейти до наступної ітерації.

Приклад із циклом for:

In [4]: for num in range(5):
   ...:     if num == 3:
   ...:         continue
   ...:     else:
   ...:         print(num)
   ...:
0
1
2
4

Приклад із циклом while:

In [5]: i = 0
In [6]: while i < 6:
   ....:     i += 1
   ....:     if i == 3:
   ....:         print("Пропускаем 3")
   ....:         continue
   ....:         print("Это никто не увидит")
   ....:     else:
   ....:         print("Текущее значение: ", i)
   ....:
Текущее значение:  1
Текущее значение:  2
Пропускаем 3
Текущее значение:  4
Текущее значение:  5
Текущее значение:  6

Використання continue у прикладі із запитом пароля (файл check_password_with_while_continue.py):

username = input('Введите имя пользователя: ')
password = input('Введите пароль: ')

password_correct = False

while not password_correct:
    if len(password) < 8:
        print('Пароль слишком короткий\n')
    elif username in password:
        print('Пароль содержит имя пользователя\n')
    else:
        print('Пароль для пользователя {} установлен'.format(username))
        password_correct = True
        continue
    password = input('Введите пароль еще раз: ')

Тут вихід із циклу виконуються за допомогою перевірки прапора password_correct. Коли було введено правильний пароль, прапор виставляється рівним True, і з допомогою continue виконується перехід початку циклу, перескочивши останній рядок із запитом пароля.

Результат виконання буде таким:

$ python check_password_with_while_continue.py
Введите имя пользователя: nata
Введите пароль: nata12
Пароль слишком короткий

Введите пароль еще раз: natalksdjflsdjf
Пароль содержит имя пользователя

Введите пароль еще раз: asdfsujljhdflaskjdfh
Пароль для пользователя nata установлен

Оператор pass

Оператор passнічого не робить. Фактично це така заглушка для об’єктів.

Наприклад, passможе допомогти ситуації, коли потрібно прописати структуру скрипта. Його можна ставити у циклах, функціях, класах. І це не впливатиме на виконання коду.

Приклад використання pass:

In [6]: for num in range(5):
   ....:     if num < 3:
   ....:         pass
   ....:     else:
   ....:         print(num)
   ....:
3
4

for/else, while/else

У циклах for і while опціонально можна використовувати блок else.

for/

У циклі for:

  • блок else виконується у разі, якщо цикл завершив ітерацію списку

  • але else не виконується , якщо в циклі був виконаний break

Приклад циклу for з else (блок else виконується після завершення циклу for):

In [1]: for num in range(5):
   ....:     print(num)
   ....: else:
   ....:     print("Числа закончились")
   ....:
0
1
2
3
4
Числа закончились

Приклад циклу for з else і break в циклі (через break блок else не виконується):

In [2]: for num in range(5):
   ....:     if num == 3:
   ....:         break
   ....:     else:
   ....:         print(num)
   ....: else:
   ....:     print("Числа закончились")
   ....:
0
1
2

Приклад циклу for з else та continue у циклі (continue не впливає на блок else):

In [3]: for num in range(5):
   ....:     if num == 3:
   ....:         continue
   ....:     else:
   ....:         print(num)
   ....: else:
   ....:     print("Числа закончились")
   ....:
0
1
2
4
Числа закончились

while/else

У циклі while:

  • блок else виконується в тому випадку, якщо умова в while хибно

  • else не виконується , якщо в циклі був виконаний break

Приклад циклу while з else (блок else виконується після завершення циклу while):

In [4]: i = 0
In [5]: while i < 5:
  ....:     print(i)
  ....:     i += 1
  ....: else:
  ....:     print("Конец")
  ....:
0
1
2
3
4
Конец

Приклад циклу while з else та break у циклі (через break блок else не виконується):

In [6]: i = 0

In [7]: while i < 5:
  ....:     if i == 3:
  ....:         break
  ....:     else:
  ....:         print(i)
  ....:         i += 1
  ....: else:
  ....:     print("Конец")
  ....:
0
1
2

Робота з винятками try/except/else/finally

Якщо ви повторювали приклади, які використовувалися раніше, то, напевно, були ситуації, коли вискакувала помилка. Швидше за все, це була помилка синтаксису, коли не вистачало, наприклад, двокрапки.

Як правило, Python досить зрозуміло реагує на такі помилки, і їх можна виправити.

Проте, навіть якщо код синтаксично написаний правильно, можуть бути помилки. У Python ці помилки називаються виняток (exceptions) .

Приклади винятків:

In [1]: 2/0
-----------------------------------------------------
ZeroDivisionError: division by zero

In [2]: 'test' + 2
-----------------------------------------------------
TypeError: must be str, not int

У цьому випадку виникли два винятки: ZeroDivisionError та TypeError .

Найчастіше можна передбачити, які винятки виникнуть під час виконання програми.

Наприклад, якщо програма на вхід очікує два числа, а на виході видає їх суму, а користувач ввів замість одного з чисел рядок, з’явиться помилка TypeError, як у прикладі вище.

Python дозволяє працювати з винятками. Їх можна перехоплювати та виконувати певні дії у тому випадку, якщо виник виняток.

Коли у програмі виникає виняток, вона одразу завершує роботу.

Для роботи з винятками використовується конструкція try/except:

In [3]: try:
   ...:     2/0
   ...: except ZeroDivisionError:
   ...:     print("You can't divide by zero")
   ...:
You can't divide by zero

Конструкція try працює таким чином:

  • спочатку виконуються вирази, які записані в блоці try

  • якщо під час виконання блоку try не виникло жодних винятків, блок except пропускається, і виконується подальший код

  • якщо під час виконання блоку try в якомусь місці виник виняток, частина блоку try, що залишилася, пропускається якщо в блоці except зазначено виняток, який виник, виконується код у блоці except. Якщо виняток, який виник, не вказано в блоці except, виконання програми переривається та видається помилка.

Зауважте, що рядок Cool!у блоці try не виводиться:

In [4]: try:
   ...:     print("Let's divide some numbers")
   ...:     2/0
   ...:     print('Cool!')
   ...: except ZeroDivisionError:
   ...:     print("You can't divide by zero")
   ...:
Let's divide some numbers
You can't divide by zero

У конструкції try/except може бути багато except, якщо потрібні різні дії, залежно від типу помилки.

Наприклад, скрипт divide.py ділить два числа введених користувачем:

# -*- coding: utf-8 -*-

try:
    a = input("Введите первое число: ")
    b = input("Введите второе число: ")
    print("Результат: ", int(a)/int(b))
except ValueError:
    print("Пожалуйста, вводите только числа")
except ZeroDivisionError:
    print("На ноль делить нельзя")

Приклади виконання скрипту:

$ python divide.py
Введите первое число: 3
Введите второе число: 1
Результат:  3

$ python divide.py
Введите первое число: 5
Введите второе число: 0
На ноль делить нельзя

$ python divide.py
Введите первое число: qewr
Введите второе число: 3
Пожалуйста, вводите только числа

У цьому випадку виняток ValueError виникає, коли користувач ввів рядок замість числа під час переведення рядка в число. Виняток ZeroDivisionError виникає у разі, якщо друге число дорівнювало 0.

Якщо немає потреби виводити різні повідомлення на помилки ValueError та ZeroDivisionError, можна зробити так (файл divide_ver2.py):

# -*- coding: utf-8 -*-

try:
    a = input("Введите первое число: ")
    b = input("Введите второе число: ")
    print("Результат: ", int(a)/int(b))
except (ValueError, ZeroDivisionError):
    print("Что-то пошло не так...")

Перевірте:

$ python divide_ver2.py
Введите первое число: wer
Введите второе число: 4
Что-то пошло не так...

$ python divide_ver2.py
Введите первое число: 5
Введите второе число: 0
Что-то пошло не так...

У блоці except можна не вказувати конкретний виняток або виняток. У такому разі перехоплюватимуться всі винятки.

Це робити не рекомендується!

try/except/else

Блок finally – це ще один опціональний блок у конструкції try. Він виконується завжди незалежно від того, чи був виняток чи ні. Сюди ставляться дії, які потрібно виконати у будь-якому випадку. Наприклад, це може бути закриття файлу.

Файл divide_ver4.py із блоком finally:

# -*- coding: utf-8 -*-

try:
    a = input("Введите первое число: ")
    b = input("Введите второе число: ")
    result = int(a)/int(b)
except (ValueError, ZeroDivisionError):
    print("Что-то пошло не так...")
else:
    print("Результат в квадрате: ", result**2)
finally:
    print("Вот и сказочке конец, а кто слушал - молодец.")
# -*- coding: utf-8 -*-

try:
    a = input("Введите первое число: ")
    b = input("Введите второе число: ")
    result = int(a)/int(b)
except (ValueError, ZeroDivisionError):
    print("Что-то пошло не так...")
else:
    print("Результат в квадрате: ", result**2)
finally:
    print("Вот и сказочке конец, а кто слушал - молодец.")

Перевірте:

$ python divide_ver4.py
Введите первое число: 10
Введите второе число: 2
Результат в квадрате:  25
Вот и сказочке конец, а кто слушал - молодец.

$ python divide_ver4.py
Введите первое число: qwerewr
Введите второе число: 3
Что-то пошло не так...
Вот и сказочке конец, а кто слушал - молодец.

$ python divide_ver4.py
Введите первое число: 4
Введите второе число: 0
Что-то пошло не так...
Вот и сказочке конец, а кто слушал - молодец.

Коли використовувати винятки

Як правило, той самий код можна написати і з використанням винятків, і без них.

Наприклад, цей варіант коду:

while True:
    a = input("Введите число: ")
    b = input("Введите второе число: ")
    try:
        result = int(a)/int(b)
    except ValueError:
        print("Поддерживаются только числа")
    except ZeroDivisionError:
        print("На ноль делить нельзя")
    else:
        print(result)
        break

Можна переписати таким чином без try/except (файл try_except_divide.py):

while True:
    a = input("Введите число: ")
    b = input("Введите второе число: ")
    if a.isdigit() and b.isdigit():
        if int(b) == 0:
            print("На ноль делить нельзя")
        else:
            print(int(a)/int(b))
            break
    else:
        print("Поддерживаются только числа")

Не завжди аналогічний варіант без використання винятків буде простим і зрозумілим.

Важливо в кожній конкретній ситуації оцінювати, який варіант коду зрозуміліший, компактніший і універсальніший – з винятками або без.

Якщо ви раніше використовували якусь іншу мову програмування, є ймовірність, що використання винятків вважалося поганим тоном. У Python це не так. Щоб трохи розібратися з цим питанням, перегляньте посилання на додаткові матеріали в кінці цього розділу.

Іноді в коді треба згенерувати виняток, це можна зробити так:

raise ValueError("При выполнении команды возникла ошибка")

Вбудовані винятки

У Python є багато вбудованих винятків, кожне з яких генерується у певній ситуації.

Наприклад, TypeError зазвичай генерується, коли очікувався один тип даних, а передали інший:

In [1]: "a" + 3
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-1-5aa8a24e3e06> in <module>
----> 1 "a" + 3
TypeError: can only concatenate str (not "int") to str

ValueError коли значення не відповідає очікуваному:

In [2]: int("a")
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-2-d9136db7b558> in <module>
----> 1 int("a")
ValueError: invalid literal for int() with base 10: 'a'

Висновок

У цій статті ми пройшли важливий етап — освоїли базові інструменти створення скриптів у Python і навчилися контролювати хід виконання програм. Ви дізналися, як запускати скрипти, передавати аргументи, взаємодіяти з користувачем, а також керувати логікою за допомогою умов, циклів, логічних операторів і обробки винятків.

Ці знання — фундамент будь-якої Python-програми. Від простого запиту пароля до складних конструкцій з вкладеними циклами та обробкою помилок — усе це дозволяє писати чистий, безпечний і керований код. Найголовніше — не боятися експериментувати. Пишіть, запускайте, помиляйтесь і вчіться. Python заохочує простоту і читаємість — скористайтесь цим на повну.

Інші статті по темі
Знайшли помилку?
Якщо ви знайшли помилку, зробіть скріншот і надішліть його боту.