Перейти к содержимому

Урок: Объектно-ориентированное программирование и область видимости в Python

Урок: Объектно-ориентированное программирование и область видимости в Python

Цели урока

  • Понять основные концепции ООП
  • Научиться создавать классы и объекты
  • Изучить принципы ООП: абстракция, инкапсуляция, наследование, полиморфизм и композиция
  • Разобраться с областью видимости переменных в Python

1. Введение в ООП

Что такое ООП?

Объектно-ориентированное программирование (ООП) — это парадигма программирования, основанная на понятии "объектов", которые могут содержать данные (атрибуты) и код (методы), манипулирующий этими данными.

Python поддерживает несколько парадигм программирования:

  • Императивная
  • Структурная
  • Функциональная
  • Объектно-ориентированная

Основные понятия ООП

  • Класс — шаблон для создания объектов, описывающий их структуру и поведение.
  • Объект (экземпляр класса) — конкретная реализация класса.
  • Атрибут (поле) — переменная, хранящая данные объекта.
  • Метод — функция, определённая внутри класса для работы с объектами.

Создание класса

class Human:
    # Атрибуты класса
    animal = 'Mammal'
    species = 'Homo Sapiens'
    bipedal = True
    
    #  Метод инициализации
    def __init__(self, name, date_of_birth, height, weight):
        self.name = name
        self.date_of_birth = date_of_birth
        self.height = height
        self.weight = weight
    
    # Методы
    def speak(self, sentence):
        print(f"{self.name} говорит: {sentence}")
    
    def walk(self):
        print(f"{self.name} идет")
    
    def eat(self):
        print(f"{self.name} ест")

Создание объекта

# Создаем экземпляр класса
john = Human("Джон", "01.01.1990", 1.75, 70)
elisabeth = Human("Элизабет", "15.05.1992", 1.65, 55)

# Вызов методов
john.speak("Привет! Меня зовут Джон!")
# Джон говорит: Привет! Меня зовут Джон!
elisabeth.walk()
# Элизабет идет
Важно: Первый параметр любого метода класса — self. Это ссылка на текущий объект, через которую метод получает доступ к атрибутам и другим методам объекта.

2. Основные принципы ООП

Абстракция

Выделение существенных характеристик объекта и игнорирование несущественных деталей.

Пример:

class Figure:
    def area(self):
        pass  # Абстрактный метод, который будет реализован в дочерних классах

class Circle(Figure):
    def __init__(self, radius):
        self.radius = radius
    
    def area(self):
        return 3.14 * self.radius ** 2

class Rectangle(Figure):
    def __init__(self, width, height):
        self.width = width
        self.height = height
    
    def area(self):
        return self.width * self.height

Инкапсуляция

Скрытие внутренней реализации объекта и предоставление доступа только через определённые методы.

Пример:

class Person:
    def __init__(self, name, age):
        self.__name = name  # Приватный атрибут
        self.__age = age    # Приватный атрибут
    
    # Геттеры
    def get_name(self):
        return self.__name
    
    def get_age(self):
        return self.__age
    
    # Сеттер
    def set_age(self, age):
        if 0 < age < 122:
            self.__age = age
        else:
            raise ValueError("Некорректное значение возраста")

# Использование
person = Person("Анна", 25)
print(person.get_name())  # Анна
person.set_age(26)        # Успешно
# person.set_age(200)     # Вызовет ошибку
Примечание: В Python приватные атрибуты обозначаются двойным подчеркиванием __, но это не строгая защита — это соглашение, указывающее, что атрибут предназначен для внутреннего использования.

Наследование

Создание нового класса на основе существующего с возможностью расширения или изменения функциональности.

Пример:

class Animal:
    def __init__(self, name):
        self.name = name
    
    def speak(self):
        print(f"{self.name} издает звук")

class Dog(Animal):  # Dog наследуется от Animal
    def speak(self):  # Переопределение метода
        print(f"{self.name} лает")

class Cat(Animal):
    def speak(self):
        print(f"{self.name} мяукает")

# Использование
dog = Dog("Роки")
cat = Cat("Мурка")
dog.speak()  # Роки лает
cat.speak()  # Мурка мяукает

Полиморфизм

Способность объектов разных классов обрабатывать данные одинаковым способом, но с разной реализацией.

Пример:

def make_sound(animal):
    animal.speak()

make_sound(Dog("Роки"))    # Роки лает
make_sound(Cat("Мурка"))   # Мурка мяукает

Композиция

Создание сложных объектов путем комбинирования других объектов.

Пример:

class Engine:
    def __init__(self, power):
        self.power = power
    
    def start(self):
        print(f"Двигатель мощностью {self.power} л.с. запущен")

class Car:
    def __init__(self, engine_power):
        self.engine = Engine(engine_power)  # Композиция
    
    def start(self):
        self.engine.start()
        print("Машина поехала")

# Использование
car = Car(150)
car.start()
# Двигатель мощностью 150 л.с. запущен
# Машина поехала

3. Область видимости переменных

Область видимости определяет, где в программе можно использовать переменную.

Типы областей видимости

Глобальная область видимости

Переменные, объявленные вне функций и классов, доступны в любой части программы.

global_var = "Я глобальная переменная"

def print_global():
    print(global_var)  # Доступна внутри функции

print_global()  # Выведет: Я глобальная переменная

Локальная область видимости

Переменные внутри функций доступны только внутри этих функций.

def local_example():
    local_var = "Я локальная переменная"
    print(local_var)  # Работает

local_example()
# print(local_var)  # Ошибка! Переменная не определена

Область видимости класса

Атрибуты класса доступны через объект класса.

class VisibilityExample:
    class_var = "Атрибут класса"
    
    def __init__(self):
        self.instance_var = "Атрибут экземпляра"
    
    def print_vars(self):
        print(self.class_var)      # Доступ к атрибуту класса
        print(self.instance_var)   # Доступ к атрибуту экземпляра

obj = VisibilityExample()
obj.print_vars()

Область видимости вложенных блоков

Переменные внутри циклов и условий доступны в пределах своей области и выше.

if True:
    block_var = "Я из блока if"
    print(block_var)  # Работает

print(block_var)  # Также работает в Python (в отличие от некоторых других языков)

Пример с одинаковыми именами переменных

string = "Глобальная переменная"

def global_print():
    print(string)  # Использует глобальную переменную

def local_print():
    string = "Локальная переменная"
    print(string)  # Использует локальную переменную

class Text:
    string = "Атрибут класса"
    
    def class_print(self):
        print(self.string)  # Использует атрибут класса

# Вызов
global_print()     # Глобальная переменная
local_print()      # Локальная переменная
text = Text()
text.class_print() # Атрибут класса
Важно: Python использует правило LEGB (Local → Enclosed → Global → Built-in) для поиска переменных.

4. Практические задания

Задание 1

Создайте класс Car с атрибутами make, model, year и методом display_info(), который выводит информацию об автомобиле.

Показать решение
class Car:
    def __init__(self, make, model, year):
        self.make = make
        self.model = model
        self.year = year
    
    def display_info(self):
        print(f"{self.year} {self.make} {self.model}")

my_car = Car("Toyota", "Camry", 2020)
my_car.display_info()  # 2020 Toyota Camry

Задание 2

Создайте класс BankAccount с приватными атрибутами __balance и методами deposit(), withdraw() и get_balance(). Добавьте проверку на отрицательные суммы.

Показать решение
class BankAccount:
    def __init__(self, initial_balance=0):
        self.__balance = initial_balance
    
    def deposit(self, amount):
        if amount > 0:
            self.__balance += amount
        else:
            print("Сумма должна быть положительной")
    
    def withdraw(self, amount):
        if 0 < amount <= self.__balance:
            self.__balance -= amount
        else:
            print("Недостаточно средств или неверная сумма")
    
    def get_balance(self):
        return self.__balance

account = BankAccount(1000)
account.deposit(500)
account.withdraw(200)
print(account.get_balance())  # 1300

Задание 3

Создайте класс Rectangle с методом area(), затем создайте дочерний класс Square, наследующийся от Rectangle. Переопределите метод area() для квадрата.

Показать решение
class Rectangle:
    def __init__(self, width, height):
        self.width = width
        self.height = height
    
    def area(self):
        return self.width * self.height

class Square(Rectangle):
    def __init__(self, side):
        super().__init__(side, side)  # Вызов конструктора родителя
    
    # area() наследуется, но работает корректно для квадрата

square = Square(5)
print(square.area())  # 25

5. Заключение

Ключевые моменты

  • ООП помогает структурировать код, делая его более понятным и поддерживаемым
  • Основные принципы ООП: абстракция, инкапсуляция, наследование, полиморфизм и композиция
  • Понимание области видимости критически важно для написания корректного кода
  • В Python классы создают с помощью ключевого слова class, объекты — вызовом класса как функции

Дальнейшие шаги

  • Изучите магические методы (__str__, __len__ и др.)
  • Ознакомьтесь с паттернами проектирования
  • Практикуйтесь в создании собственных классов для решения задач
"Хороший код — это код, который легко понять и изменить." — Мартин Фаулер

Проверь себя

1. Что такое класс в Python?

  • Описание модуля библиотеки
  • Описание объекта, определяющее его свойства и методы
  • Функция, возвращающая результат
  • Конструкция для создания циклов

2. Как создать экземпляр класса в Python?

  • Использовать функцию create()
  • Использовать имя класса и скобки
  • Использовать ключевое слово new
  • Экземпляр создаётся автоматически при создании класса

3. Как получить доступ к атрибуту breed объекта rex класса Dog?

  • rex.breed
  • rex[breed]
  • Dog.breed
  • Dog.rex.breed

4. Каким ключевым словом внутри метода обозначают объект?

Ответ: self

5. Что такое инкапсуляция в ООП?

  • Механизм, который позволяет скрыть реализацию класса от пользователя
  • Механизм, который позволяет использовать разные типы данных в одном выражении
  • Механизм, который позволяет наследовать методы и атрибуты от другого класса
  • Механизм, который позволяет создавать объекты разных классов с одинаковым интерфейсом

```

Конспект:
Четверг, 28 августа 2025
Урок: Объектно-ориентированное программирование и область видимости в Python