Объектно-ориентированное программирование и области видимости в Python. [1.9]
Введение в ООП
Объектно-ориентированное программирование (ООП) — это парадигма программирования, основанная на представлении программы как совокупности объектов, каждый из которых является экземпляром определенного класса. ООП позволяет моделировать реальные системы, делая код более структурированным, поддерживаемым и переиспользуемым.
Основные понятия ООП
- Класс — шаблон или blueprint для создания объектов. Определяет атрибуты (данные) и методы (функции) объектов.
- Объект (экземпляр) — конкретная реализация класса с собственными данными.
- Атрибут — переменная, принадлежащая объекту или классу.
- Метод — функция, определенная внутри класса и работающая с объектами этого класса.
Создание классов и объектов
В Python классы создаются с помощью ключевого слова class:
class Human:
"""
Класс, представляющий человека.
Атрибуты класса (общие для всех экземпляров):
animal (str): Тип животного
species (str): Вид
bipedal (bool): Признак прямохождения
Методы:
speak(sentence): Выводит предложение
walk(): Имитирует ходьбу
eat(): Имитирует прием пищи
"""
animal = 'Mammal'
species = 'Homo Sapiens'
bipedal = True
def speak(self, sentence):
"""
Выводит предложение на экран.
Args:
sentence (str): Предложение для вывода
"""
print(sentence)
def walk(self):
"""Имитирует ходьбу человека."""
print("Человек идет")
def eat(self):
"""Имитирует прием пищи."""
print("Человек ест")
# Создание экземпляров класса
john = Human()
elisabeth = Human()
# Вызов методов
john.speak("Привет! Меня зовут Джон!")
elisabeth.speak("Привет! Меня зовут Элизабет!")
john.walk()
# Вывод:
# Привет! Меня зовут Джон!
# Привет! Меня зовут Элизабет!
# Человек идет
Важно: Первый параметр любого метода класса — self. Это ссылка на текущий экземпляр класса. При вызове метода Python автоматически передает экземпляр в качестве первого аргумента.
Конструктор __init__
Конструктор (__init__) — специальный метод, который автоматически вызывается при создании нового объекта. Он используется для инициализации атрибутов экземпляра.
class Person:
"""
Класс, представляющий человека с индивидуальными характеристиками.
Атрибуты экземпляра:
name (str): Имя человека
date_of_birth (str): Дата рождения в формате ДД.ММ.ГГГГ
height (float): Рост в метрах
weight (float): Вес в килограммах
"""
def __init__(self, name, date_of_birth, height, weight):
"""
Инициализирует новый экземпляр класса Person.
Args:
name (str): Имя человека
date_of_birth (str): Дата рождения
height (float): Рост в метрах
weight (float): Вес в килограммах
"""
self.name = name
self.date_of_birth = date_of_birth
self.height = height
self.weight = weight
def get_bmi(self):
"""
Рассчитывает индекс массы тела (ИМТ).
Returns:
float: Значение ИМТ
"""
return self.weight / (self.height ** 2)
def __str__(self):
"""
Возвращает строковое представление объекта.
Returns:
str: Информация о человеке
"""
return f"{self.name}, рост: {self.height}м, вес: {self.weight}кг"
# Создание объекта с использованием конструктора
anna = Person("Анна", "15.05.1990", 1.68, 58.5)
print(anna) # Анна, рост: 1.68м, вес: 58.5кг
print(f"ИМТ Анны: {anna.get_bmi():.1f}") # ИМТ Анны: 20.7
Столпы ООП
1. Абстракция
Абстракция — это процесс выделения существенных характеристик объекта и игнорирования несущественных деталей. Абстракция позволяет создавать простые модели сложных систем.
from abc import ABC, abstractmethod
class Figure(ABC):
"""
Абстрактный базовый класс для геометрических фигур.
Абстрактные методы (должны быть реализованы в дочерних классах):
area(): Вычисляет площадь фигуры
perimeter(): Вычисляет периметр фигуры
"""
@abstractmethod
def area(self):
"""Абстрактный метод для вычисления площади."""
pass
@abstractmethod
def perimeter(self):
"""Абстрактный метод для вычисления периметра."""
pass
class Circle(Figure):
"""
Класс, представляющий круг.
Атрибуты:
radius (float): Радиус круга
"""
def __init__(self, radius):
self.radius = radius
def area(self):
"""Вычисляет площадь круга."""
return 3.14 * self.radius ** 2
def perimeter(self):
"""Вычисляет длину окружности."""
return 2 * 3.14 * self.radius
class Rectangle(Figure):
"""
Класс, представляющий прямоугольник.
Атрибуты:
width (float): Ширина прямоугольника
height (float): Высота прямоугольника
"""
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
"""Вычисляет площадь прямоугольника."""
return self.width * self.height
def perimeter(self):
"""Вычисляет периметр прямоугольника."""
return 2 * (self.width + self.height)
# Использование абстрактного класса
shapes = [Circle(5), Rectangle(4, 6)]
for shape in shapes:
print(f"Площадь: {shape.area():.2f}, Периметр: {shape.perimeter():.2f}")
# Площадь: 78.50, Периметр: 31.40
# Площадь: 24.00, Периметр: 20.00
Пояснение: ABC (Abstract Base Class) — это базовый класс для создания абстрактных классов. Абстрактные методы помечаются декоратором @abstractmethod и должны быть реализованы во всех дочерних классах.
2. Инкапсуляция
Инкапсуляция — это механизм сокрытия внутреннего устройства объекта и предоставления интерфейса для взаимодействия с ним. В Python инкапсуляция реализуется через соглашения об именовании:
_var— защищенный (protected) атрибут/метод (соглашение, что не следует использовать вне класса)__var— приватный (private) атрибут/метод (Python изменяет имя для сокрытия)
class BankAccount:
"""
Класс банковского счета с инкапсуляцией данных.
Атрибуты:
_account_number (str): Защищенный номер счета
__balance (float): Приватный баланс счета
owner (str): Владелец счета
"""
def __init__(self, account_number, balance, owner):
self._account_number = account_number # Защищенный атрибут
self.__balance = balance # Приватный атрибут
self.owner = owner
def deposit(self, amount):
"""
Пополняет счет на указанную сумму.
Args:
amount (float): Сумма пополнения
Returns:
bool: Успешность операции
"""
if amount <= 0:
print("Сумма должна быть положительной")
return False
self.__balance += amount
return True
def withdraw(self, amount):
"""
Снимает деньги со счета.
Args:
amount (float): Сумма для снятия
Returns:
bool: Успешность операции
"""
if amount <= 0:
print("Сумма должна быть положительной")
return False
if amount > self.__balance:
print("Недостаточно средств")
return False
self.__balance -= amount
return True
def get_balance(self):
"""
Возвращает текущий баланс.
Returns:
float: Текущий баланс
"""
return self.__balance
def __str__(self):
"""Возвращает строковое представление счета."""
return f"Счет {self._account_number[-4:]} владельца {self.owner}"
# Использование инкапсуляции
account = BankAccount("RU1234567890", 1000.0, "Иван Петров")
print(account) # Счет 7890 владельца Иван Петров
account.deposit(500.0)
print(f"Баланс: {account.get_balance()}") # Баланс: 1500.0
# Попытка прямого доступа к приватному атрибуту
# print(account.__balance) # AttributeError: 'BankAccount' object has no attribute '__balance'
# print(account._BankAccount__balance) # 1500.0 (обход инкапсуляции, но не рекомендуется)
Важно: В Python инкапсуляция реализована на уровне соглашений, а не строгого синтаксиса. Приватные атрибуты можно получить через _ClassName__attribute, но это нарушает принципы инкапсуляции.
3. Наследование
Наследование — это механизм создания нового класса на основе существующего. Дочерний класс наследует атрибуты и методы родительского класса, может расширять их или переопределять.
class Animal:
"""
Базовый класс для всех животных.
Атрибуты:
name (str): Имя животного
species (str): Вид животного
"""
def __init__(self, name, species):
self.name = name
self.species = species
def make_sound(self):
"""Базовый метод для издавания звука."""
print(f"{self.name} издает звук")
def __str__(self):
return f"{self.name} ({self.species})"
class Dog(Animal):
"""
Класс собаки, наследующий от Animal.
Атрибуты:
breed (str): Порода собаки
"""
def __init__(self, name, breed):
# Вызов конструктора родительского класса
super().__init__(name, "Собака")
self.breed = breed
def make_sound(self):
"""Переопределенный метод для лая собаки."""
print(f"{self.name} гавкает: Гав-гав!")
def fetch(self):
"""Специфический метод для собаки."""
print(f"{self.name} приносит палку")
class Cat(Animal):
"""
Класс кошки, наследующий от Animal.
Атрибуты:
color (str): Цвет кошки
"""
def __init__(self, name, color):
super().__init__(name, "Кошка")
self.color = color
def make_sound(self):
"""Переопределенный метод для мяуканья кошки."""
print(f"{self.name} мяукает: Мяу!")
def scratch(self):
"""Специфический метод для кошки."""
print(f"{self.name} царапает диван")
# Создание объектов
dog = Dog("Рекс", "Овчарка")
cat = Cat("Мурка", "Серый")
animals = [dog, cat]
for animal in animals:
print(animal)
animal.make_sound()
# Проверка типа для вызова специфических методов
if isinstance(animal, Dog):
animal.fetch()
elif isinstance(animal, Cat):
animal.scratch()
# Вывод:
# Рекс (Собака)
# Рекс гавкает: Гав-гав!
# Рекс приносит палку
# Мурка (Кошка)
# Мурка мяукает: Мяу!
# Мурка царапает диван
Пояснение:
super()— позволяет вызывать методы родительского классаisinstance()— проверяет, является ли объект экземпляром указанного класса- Переопределение методов (
make_sound) позволяет изменять поведение в дочерних классах
4. Полиморфизм
Полиморфизм — это возможность использовать объекты разных классов через единый интерфейс. Благодаря полиморфизму один и тот же метод может вести себя по-разному для разных объектов.
class Shape:
"""Абстрактный базовый класс для геометрических фигур."""
def area(self):
"""Абстрактный метод для вычисления площади."""
raise NotImplementedError("Метод area() должен быть реализован в дочернем классе")
def __str__(self):
"""Возвращает строковое представление фигуры."""
return self.__class__.__name__
class Square(Shape):
"""Класс квадрата."""
def __init__(self, side):
self.side = side
def area(self):
"""Вычисляет площадь квадрата."""
return self.side ** 2
class Triangle(Shape):
"""Класс треугольника."""
def __init__(self, base, height):
self.base = base
self.height = height
def area(self):
"""Вычисляет площадь треугольника."""
return 0.5 * self.base * self.height
class Circle(Shape):
"""Класс круга."""
def __init__(self, radius):
self.radius = radius
def area(self):
"""Вычисляет площадь круга."""
return 3.14 * self.radius ** 2
# Полиморфизм в действии
shapes = [
Square(5),
Triangle(4, 6),
Circle(3)
]
for shape in shapes:
print(f"{shape}: площадь = {shape.area():.2f}")
# Вывод:
# Square: площадь = 25.00
# Triangle: площадь = 12.00
# Circle: площадь = 28.26
Важно: Полиморфизм позволяет работать с объектами разных классов через единый интерфейс (area()), не зная их конкретного типа во время выполнения.
5. Композиция
Композиция — это механизм создания сложных объектов путем объединения более простых. В отличие от наследования, композиция основана на отношении "имеет" (has-a), а не "является" (is-a).
class Engine:
"""
Класс двигателя автомобиля.
Атрибуты:
power (int): Мощность двигателя в лошадиных силах
fuel_type (str): Тип топлива
"""
def __init__(self, power, fuel_type="Бензин"):
self.power = power
self.fuel_type = fuel_type
def start(self):
"""Запускает двигатель."""
print(f"Двигатель мощностью {self.power} л.с. запущен на {self.fuel_type}")
def stop(self):
"""Останавливает двигатель."""
print("Двигатель остановлен")
class Wheels:
"""
Класс колес автомобиля.
Атрибуты:
count (int): Количество колес
size (str): Размер колес
"""
def __init__(self, count=4, size="R16"):
self.count = count
self.size = size
def rotate(self):
"""Имитирует вращение колес."""
print(f"Все {self.count} колеса размера {self.size} вращаются")
class Car:
"""
Класс автомобиля, использующий композицию.
Атрибуты:
engine (Engine): Двигатель автомобиля
wheels (Wheels): Колеса автомобиля
brand (str): Марка автомобиля
model (str): Модель автомобиля
"""
def __init__(self, brand, model, engine_power, wheel_count=4, wheel_size="R16"):
# Создание компонентов через композицию
self.engine = Engine(engine_power)
self.wheels = Wheels(wheel_count, wheel_size)
self.brand = brand
self.model = model
def start(self):
"""Запускает автомобиль."""
print(f"Запуск автомобиля {self.brand} {self.model}")
self.engine.start()
self.wheels.rotate()
print("Автомобиль готов к движению")
def stop(self):
"""Останавливает автомобиль."""
print(f"Остановка автомобиля {self.brand} {self.model}")
self.engine.stop()
print("Автомобиль остановлен")
# Использование композиции
my_car = Car("Toyota", "Camry", 200)
my_car.start()
my_car.stop()
# Вывод:
# Запуск автомобиля Toyota Camry
# Двигатель мощностью 200 л.с. запущен на Бензин
# Все 4 колеса размера R16 вращаются
# Автомобиль готов к движению
# Остановка автомобиля Toyota Camry
# Двигатель остановлен
# Автомобиль остановлен
Преимущества композиции перед наследованием:
- Гибкость: можно легко заменить компоненты
- Повторное использование кода: одни и те же компоненты можно использовать в разных классах
- Упрощение иерархии классов
- Легче тестировать отдельные компоненты
Области видимости переменных
Область видимости определяет, где в программе можно использовать переменную. В Python существует несколько типов областей видимости, которые следуют правилу LEGB:
- Local (локальная) — внутри функции
- Enclosing (обрамляющая) — вложенные функции
- Global (глобальная) — на уровне модуля
- Built-in (встроенная) — встроенные имена Python
Глобальная область видимости
Переменные, объявленные на уровне модуля (вне функций и классов), имеют глобальную область видимости.
# Глобальные переменные
global_var = "Я глобальная переменная"
PI = 3.14159 # Константы обычно пишутся заглавными буквами
def access_global():
"""Функция может читать глобальные переменные."""
print(f"В функции: {global_var}")
print(f"Число PI: {PI}")
def modify_global():
"""Для изменения глобальной переменной нужно использовать ключевое слово global."""
global global_var
global_var = "Я измененная глобальная переменная"
print(f"Измененная в функции: {global_var}")
# Использование
access_global()
# В функции: Я глобальная переменная
# Число PI: 3.14159
modify_global()
print(f"После изменения: {global_var}")
# Измененная в функции: Я измененная глобальная переменная
# После изменения: Я измененная глобальная переменная
Локальная область видимости
Переменные, объявленные внутри функции, имеют локальную область видимости и доступны только внутри этой функции.
def local_scope_example():
"""Демонстрация локальной области видимости."""
local_var = "Я локальная переменная"
print(local_var)
# Вложенные блоки (if, for, while) не создают новую область видимости
if True:
nested_var = "Я в локальной области, но в блоке if"
print(nested_var)
# nested_var доступна вне блока if, но только внутри функции
print(f"Все еще доступна: {nested_var}")
local_scope_example()
# print(local_var) # NameError: name 'local_var' is not defined
Область видимости классов
Атрибуты класса и экземпляра имеют свою область видимости, ограниченную классом и его методами.
class ScopeExample:
"""Класс для демонстрации областей видимости."""
class_var = "Атрибут класса" # Доступен всем экземплярам
def __init__(self, instance_var):
self.instance_var = instance_var # Атрибут экземпляра
def method(self):
"""Метод с доступом к разным областям видимости."""
local_var = "Локальная переменная метода"
print(f"В методе:")
print(f" - Атрибут класса: {self.class_var}")
print(f" - Атрибут экземпляра: {self.instance_var}")
print(f" - Локальная переменная: {local_var}")
@classmethod
def class_method(cls):
"""Метод класса имеет доступ к атрибутам класса."""
print(f"В методе класса: {cls.class_var}")
# print(cls.instance_var) # AttributeError: type object 'ScopeExample' has no attribute 'instance_var'
@staticmethod
def static_method():
"""Статический метод не имеет доступа к атрибутам экземпляра или класса."""
print("В статическом методе")
# print(self.class_var) # NameError: name 'self' is not defined
# print(cls.class_var) # NameError: name 'cls' is not defined
# Создание экземпляра
obj = ScopeExample("Атрибут экземпляра")
# Доступ к атрибутам
print(f"Вне класса:")
print(f" - Атрибут класса: {ScopeExample.class_var}")
print(f" - Атрибут экземпляра: {obj.instance_var}")
# Вызов методов
obj.method()
ScopeExample.class_method()
ScopeExample.static_method()
# Попытка доступа к локальной переменной извне
# print(local_var) # NameError: name 'local_var' is not defined
Вложенные функции и nonlocal
В Python функции могут быть вложенными. Для доступа к переменным обрамляющей функции используется ключевое слово nonlocal.
def outer_function():
"""Внешняя функция с вложенной функцией."""
outer_var = "Переменная внешней функции"
def inner_function():
"""Вложенная функция."""
nonlocal outer_var # Указываем, что используем переменную из внешней области
outer_var = "Измененная переменная внешней функции"
print(f"Во вложенной функции: {outer_var}")
print(f"До вызова вложенной функции: {outer_var}")
inner_function()
print(f"После вызова вложенной функции: {outer_var}")
outer_function()
# Вывод:
# До вызова вложенной функции: Переменная внешней функции
# Во вложенной функции: Измененная переменная внешней функции
# После вызова вложенной функции: Измененная переменная внешней функции
Чек-лист по статье 1.9
Объектно-ориентированное программирование
- Я понимаю разницу между классом и объектом (экземпляром)
- Я могу создавать классы с атрибутами и методами
- Я знаю, как использовать конструктор
__init__для инициализации объектов - Я понимаю назначение ключевого слова
selfв методах - Я могу создавать абстрактные базовые классы с помощью
ABCи@abstractmethod - Я понимаю принцип инкапсуляции и знаю соглашения об именовании (
_var,__var) - Я могу создавать дочерние классы с помощью наследования
- Я умею использовать
super()для вызова методов родительского класса - Я понимаю концепцию полиморфизма и могу применять ее на практике
- Я знаю разницу между наследованием и композицией
- Я могу создавать классы с использованием композиции
- Я понимаю, когда использовать наследование, а когда композицию
Области видимости
- Я знаю правило LEGB (Local, Enclosing, Global, Built-in)
- Я могу объявлять и использовать глобальные переменные
- Я понимаю, когда нужно использовать ключевое слово
global - Я знаю, что локальные переменные доступны только внутри функции
- Я понимаю разницу между атрибутами класса и атрибутами экземпляра
- Я знаю, как работают методы класса (
@classmethod) и статические методы (@staticmethod) - Я понимаю концепцию вложенных функций и знаю, когда использовать
nonlocal - Я могу объяснять цепочку поиска переменных в Python
- Я понимаю, почему глобальные переменные следует использовать осторожно
- Я знаю, как избегать конфликтов имен в разных областях видимости
Практические навыки
- Я могу документировать классы и методы с помощью docstrings
- Я умею создавать строковые представления объектов с помощью
__str__ - Я могу проверять типы объектов с помощью
isinstance()иtype() - Я понимаю, как работать с приватными атрибутами и когда их использовать
- Я могу создавать иерархии классов с использованием наследования
- Я умею переопределять методы в дочерних классах
- Я понимаю, как создавать интерфейсы с помощью абстрактных классов
- Я могу проектировать системы с использованием композиции вместо наследования
- Я знаю, как управлять областями видимости для написания чистого кода
- Я понимаю, как избегать побочных эффектов при работе с глобальными переменными
Заключение
Объектно-ориентированное программирование и понимание областей видимости — это фундаментальные концепции, которые позволяют писать качественный, поддерживаемый и масштабируемый код на Python. ООП помогает моделировать реальные системы, делая код более структурированным и интуитивно понятным, а правильное управление областями видимости предотвращает ошибки и делает программу более предсказуемой.
Ключевые принципы ООП (абстракция, инкапсуляция, наследование, полиморфизм и композиция) работают вместе, создавая мощную парадигму для разработки программного обеспечения. Понимание областей видимости (глобальной, локальной, классовой и вложенных) помогает избежать многих распространенных ошибок и делает код более чистым.
В следующих статьях мы углубимся в более продвинутые темы Python, такие как декораторы, генераторы, асинхронное программирование и работу с базами данных.
Приложение 1: Исключения в Python
Ключевое слово raise используется в Python для явной генерации (выброса) исключений. Это позволяет создавать исключения при нарушении условий, повышать уровень перехваченных исключений или вызывать пользовательские исключения для специфичных ситуаций.
Таблицы исключений Python
Таблица 1: Основные встроенные исключения
| Категория | Исключение | Когда возникает | Пример |
|---|---|---|---|
| Базовые | Exception |
Базовый класс всех исключений | except Exception as e: |
BaseException |
Родитель всех исключений | Редко используется напрямую | |
| Арифметические | ArithmeticError |
Базовый класс для арифметических ошибок | В иерархии исключений |
ZeroDivisionError |
Деление на ноль | 10 / 0 |
|
OverflowError |
Результат операции слишком велик | 10 ** 1000 (в некоторых случаях) |
|
| Типы данных | TypeError |
Неправильный тип данных | "5" + 3 |
ValueError |
Неправильное значение | int("abc") |
|
| Работа с коллекциями | LookupError |
Базовый класс для ошибок поиска | В иерархии исключений |
IndexError |
Индекс вне диапазона | lst[10] для списка из 5 элементов |
|
KeyError |
Ключ не найден в словаре | dct["несуществующий_ключ"] |
|
| Ввод-вывод | IOError/OSError |
Ошибка ввода-вывода | Проблемы с чтением/записью файлов |
FileNotFoundError |
Файл не найден | open("несуществующий_файл.txt") |
|
| Атрибуты | AttributeError |
Атрибут объекта не найден | obj.несуществующий_атрибут |
| Импорт | ImportError |
Ошибка импорта модуля | import несуществующий_модуль |
Таблица 2: Специализированные исключения
| Библиотека | Исключение | Когда возникает | Пример обработки |
|---|---|---|---|
| Requests (сетевые запросы) |
ConnectionError |
Проблемы с сетевым соединением | except requests.exceptions.ConnectionError: |
Timeout |
Таймаут запроса | except requests.exceptions.Timeout: |
|
HTTPError |
HTTP ошибка (4xx, 5xx) | except requests.exceptions.HTTPError: |
|
RequestException |
Базовый класс всех исключений requests | except requests.exceptions.RequestException: |
|
| SQLite3 (работа с БД) |
sqlite3.Error |
Базовый класс ошибок SQLite | except sqlite3.Error as e: |
sqlite3.IntegrityError |
Нарушение целостности данных | except sqlite3.IntegrityError: |
|
sqlite3.OperationalError |
Ошибка операций с БД | except sqlite3.OperationalError: |
|
| JSON | json.JSONDecodeError |
Ошибка декодирования JSON | except json.JSONDecodeError: |
Практические примеры с raise
def calculate_average(numbers):
if not numbers:
raise ValueError("Список чисел не должен быть пустым")
if not all(isinstance(x, (int, float)) for x in numbers):
raise TypeError("Все элементы должны быть числами")
return sum(numbers) / len(numbers)
def process_file(filename):
try:
with open(filename, 'r') as file:
return file.read()
except PermissionError:
print(f"Нет доступа к файлу {filename}")
raise # Повторно выбрасываем то же исключение
def parse_user_input(input_str):
try:
return int(input_str)
except ValueError as e:
raise ValueError(f"Невозможно преобразовать '{input_str}' в число") from e
Иерархия исключений (сокращенная)
BaseException
├── KeyboardInterrupt
├── SystemExit
└── Exception
├── ArithmeticError
│ ├── ZeroDivisionError
│ └── OverflowError
├── LookupError
│ ├── IndexError
│ └── KeyError
├── ValueError
├── TypeError
├── IOError
│ └── FileNotFoundError
└── [Пользовательские исключения]
Лучшие практики работы с исключениями
except:finally или контекстные менеджеры (with)Шпаргалка по обработке исключений
try:
# Код, который может вызвать исключение
risky_operation()
except SpecificException as e:
# Обработка конкретного исключения
print(f"Конкретная ошибка: {e}")
except (AnotherException, DifferentException) as e:
# Обработка нескольких типов исключений
print(f"Одна из ошибок: {e}")
except Exception as e:
# Обработка всех остальных исключений
print(f"Неожиданная ошибка: {e}")
# Логирование или повторный выброс
raise
else:
# Выполняется, если исключений не было
print("Операция успешна")
finally:
# Выполняется всегда
print("Завершение операции")
Примечание: Это приложение является дополнением к основной статье об условных операторах, циклах и исключениях. Здесь собрана справочная информация для быстрого доступа и повторения материала.
Ссылки по теме
- Функции в Python: основные строительные блоки программ [1.5]
- Ввод и вывод данных. Форматирование. Работа с файлами. [1.6 ]
- Условный оператор и циклы в Python [1.7]
![Объектно-ориентированное программирование и области видимости в Python. [1.9] Объектно-ориентированное программирование и области видимости в Python. [1.9]](https://www.technobee.ru/media/zoo/images/line100_python_24f065d5f44b128d7987e916e0a668ad.png)