7. Основы Python. Часть III - qa-guru/knowledge-base GitHub Wiki
Данный раздел разделен на несколько частей(каждый пункт - это ссылка на соответствующий раздел):
Переход по внутренним ссылкам происходит только при открытом разделе блока в котором находится ссылка.
ООП - это объектно-ориентированное программирование, которое позволяет описывать объекты и их взаимодействие между собой. ООП сосредотачивается на создании объектов, которые содержат как данные, так и код, чтобы манипулировать данными. ООП позволяет создавать объекты, которые могут взаимодействовать друг с другом, обмениваясь данными и информацией. Под объектом понимается экземпляр класса. Класс - это шаблон для создания объектов. Он определяет атрибуты и методы, которые будут у объектов этого класса. Атрибуты - это переменные, которые хранят данные. А методы - это функции, которые могут быть вызваны для выполнения действий.
Пример класса:
class Person: # это класс Person
def __init__(self, name, age): # это конструктор класса
self.name = name # это атрибут класса
self.age = age # это атрибут класса
def say_hello(self): # это метод класса, который выводит приветствие и насчитывает возраст. Наследует атрибуты класса(self.name, self.age)
print(f'Hello, my name is {self.name} and I am {self.age} years old') В коде выше объектом называют экземпляр класса Person. Экземпляр класса создается с помощью вызова класса, как если бы это была функция. В примере выше создание объекта выглядит так:
person = Person('John', 25) # создание объекта класса PersonВ примере выше person - это объект класса Person. Он содержит атрибуты name и age, которые были переданы в конструктор класса. Также у объекта есть метод say_hello, который можно вызвать, используя точку:
person.say_hello() # вызов метода say_hello у объекта person
# Output:
# Hello, my name is John and I am 25 years oldПреимущества ООП:
- Повторное использование кода - объекты могут быть использованы в разных частях программы.
- Модульность кода - объекты могут быть использованы для разделения кода на более мелкие части.
- Гибкость кода - объекты могут быть легко изменены и расширены.
- Безопасность кода - программы, написанные с использованием ООП, обычно более надежны и безопасны.
Недостатки ООП:
- Сложность - ООП может быть сложным для понимания и использования.
- Производительность - ООП может быть менее эффективным с точки зрения производительности, чем другие подходы к программированию.
- Размер - ООП может привести к созданию больших программ, которые могут быть сложными для управления.
- Абстракция
- Инкапсуляция
- Наследование
- Полиморфизм
Нажать, чтобы раскрыть
Абстракция - это процесс создания модели объекта. Который содержит только те аспекты объекта, которые важны для решения конкретной задачи. Она позволяет скрыть сложность объекта от пользователя. В Python абстракция реализуется с помощью классов. Класс - это шаблон для создания объектов. Он определяет атрибуты и методы, которые будут у объектов этого класса.
Пример абстракции:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def say_hello(self):
print(f'Hello, my name is {self.name} and I am {self.age} years old')
person = Person('John', 25) # создание объекта класса Person
person.say_hello() # вызов метода say_hello у объекта
# Output:
# Hello, my name is John and I am 25 years oldВ примере выше класс Person - это абстракция объекта человека. Он содержит атрибуты name и age, которые характеризуют человека. И метод say_hello, который позволяет человеку поздороваться. Таким образом, класс Person абстрагирует объект человека, скрывая его сложность от пользователя.
Нажать, чтобы раскрыть
Инкапсуляция - это прием программирования, который позволяет разбить сложную систему на более простые части. Она позволяет скрыть сложность системы от пользователя.
Пример инкапсуляции:
class Person:
def __init__(self, name, age):
self._name = name
self._age = age
def get_name(self):
return self._name
def set_name(self, name):
self._name = name
def get_age(self):
return self._age
def set_age(self, age):
self._age = age
person = Person('John', 25) # создание объекта класса Person
print(person.get_name()) # вызов метода get_name у объекта person
print(person.get_age()) # вызов метода get_age у объекта person
# Output:
# John
# 25В примере выше атрибуты name и age инкапсулированы в классе Person. Они доступны только через методы get_name, set_name, get_age и set_age. Таким образом, инкапсуляция позволяет скрыть сложность атрибутов от пользователя и предоставить удобный интерфейс для работы с ними. set_name и set_age - это методы для установки значений атрибутов name и age. get_name и get_age - это методы для получения значений атрибутов name и age. Таким образом, инкапсуляция позволяет создавать более безопасный и удобный интерфейс для работы с атрибутами объекта.
Нажать, чтобы раскрыть
Наследование - это процесс создания нового класса на основе существующего класса. Новый класс называется подклассом, а существующий класс называется супер классом. Подкласс наследует атрибуты и методы супер класса и может добавлять к ним новые атрибуты и методы.
Пример наследования:
class Student(Person):
def __init__(self, name, age, grade):
super().__init__(name, age)
self.grade = grade
def get_grade(self):
return self.grade
student = Student('John', 25, 'A') # создание объекта класса Student
print(student.get_name()) # вызов метода get_name у объекта student
print(student.get_age()) # вызов метода get_age у объекта student
print(student.get_grade()) # вызов метода get_grade у объекта student
# Output:
# John
# 25
# AВ примере выше класс Student наследует атрибуты и методы класса Person. Он добавляет к ним новый атрибут grade и метод get_grade. Таким образом, наследование позволяет создавать новые классы на основе существующих классов и повторно использовать код.
Нажать, чтобы раскрыть
Полиморфизм - это возможность объектов с одинаковым интерфейсом иметь различную реализацию. Это позволяет использовать объекты разных классов в одном и том же контексте.
Пример полиморфизма:
class Dog:
def speak(self):
return 'Woof!'
class Cat:
def speak(self):
return 'Meow!'
def get_pet_sound(pet):
return pet.speak()
dog = Dog()
cat = Cat()
print(get_pet_sound(dog)) # вызов функции get_pet_sound с объектом dog
print(get_pet_sound(cat)) # вызов функции get_pet_sound с объектом cat
# Output:
# Woof!
# Meow!В примере выше классы Dog и Cat имеют метод speak с одинаковым интерфейсом. Однако у них различная реализация этого метода. Таким образом, полиморфизм позволяет использовать объекты разных классов в одном и том же контексте. Аргумент pet функции get_pet_sound может быть объектом любого класса, который имеет метод speak. Таким образом, полиморфизм позволяет создавать более гибкий и универсальный код.
Нажать, чтобы раскрыть
Модули и классы являются основными строительными блоками в Python. Модули - это файлы, содержащие определения функций, классов и переменных, которые можно использовать в разных частях программы. Классы - это шаблоны для создания объектов. Они определяют атрибуты и методы, которые будут у объектов этого класса.
Пример модуля:
# file: automation.py
import time
def wait(seconds):
time.sleep(seconds)
class Browser:
def __init__(self, url):
self.url = url
def open(self):
print(f'Opening {self.url} in the browser')
def close(self):
print('Closing the browser')В примере выше, файл automation.py содержит определение функции wait и класса Browser. Эти определения могут быть использованы в других файлах с помощью импорта:
# file: main.py
import automation
automation.wait(5) # вызов функции wait из модуля automation
browser = automation.Browser('https://www.github.com') # создание объекта класса Browser из модуля automation
browser.open() # вызов метода open у объекта browser
automation.wait(5) # ожидание 5 секунд
browser.close() # вызов метода close у объекта browser
# Output:
# Opening https://www.github.com in the browser
# Closing the browserВ примере выше, файл main.py импортирует модуль automation и использует его определения. Таким образом, модули позволяют организовать код в более мелкие части и повторно использовать его в разных частях программы.
Нажать, чтобы раскрыть
self - это ссылка на текущий объект. Она используется для доступа к атрибутам и методам объекта внутри его методов. В Python self - это обязательный параметр для всех методов объекта, который передается автоматически при вызове метода.
Пример использования self:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def say_hello(self):
print(f'Hello, my name is {self.name} and I am {self.age} years old')
person = Person('John', 25) # создание объекта класса Person
person.say_hello() # вызов метода say_hello у объекта
# Output:
# Hello, my name is John and I am 25 years oldВ примере выше self используется для доступа к атрибутам name и age объекта внутри метода say_hello. Таким образом, self позволяет объекту взаимодействовать с самим собой.
Нажать, чтобы раскрыть
__init__() - это конструктор класса. Он вызывается при создании объекта класса и используется для инициализации его атрибутов.
Инициализация атрибутов происходит с помощью параметров, переданных в конструктор при создании объекта.
Инициализация это процесс задания начальных значений атрибутам объекта.
Пример использования init() в классе:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
person = Person('John', 25) # создание объекта класса Person
print(person.name) # доступ к атрибуту name объекта
print(person.age) # доступ к атрибуту age объекта
# Output:
# John
# 25В примере выше конструктор класса Person принимает два параметра: name и age. Он использует их для инициализации атрибутов name и age объекта. Таким образом, init() позволяет задать начальные значения атрибутам объекта при его создании.
Нажать, чтобы раскрыть
@classmethod - это декоратор, который используется для определения метода класса. Метод класса принимает первым параметром ссылку на класс, а не на объект. Он может быть вызван как от объекта, так и от класса.
Пример использования @classmethod:
class Person:
count = 0 # атрибут класса
def __init__(self, name, age):
self.name = name
self.age = age
Person.count += 1 # увеличение счетчика при создании объекта
@classmethod
def get_count(cls): # метод класса
return cls.count
person1 = Person
person2 = Person
print(person1.get_count()) # вызов метода get_count от класса
print(person2.get_count()) # вызов метода get_count от класса
# Output:
# 2 # значение атрибута count = 2 потому что создано 2 объекта
# 2В примере выше метод get_count класса Person помечен декоратором @classmethod. Он принимает первым параметром ссылку на класс (cls) и возвращает значение атрибута count. Таким образом, метод класса позволяет получить доступ к атрибутам класса и использовать их внутри метода.
Еще пример использования @classmethod:
class Math:
@classmethod
def add(cls, a, b):
return a + b
print(Math.add(2, 3)) # вызов метода add от класса
math = Math()
print(math.add(2, 3)) # вызов метода add от объекта
# Output:
# 5
# 5В примере выше метод add класса Math помечен декоратором @classmethod. Он принимает первым параметром ссылку на класс (cls) и возвращает сумму двух чисел. Таким образом, метод класса позволяет создавать функции, которые могут быть вызваны как от объекта, так и от класса.
Нажать, чтобы раскрыть
@staticmethod - это декоратор, который используется для определения статического метода. Статический метод не принимает ссылку на объект или класс и может быть вызван как от объекта, так и от класса.
Пример использования @staticmethod:
class Person:
@staticmethod
def say_hello(name): # статический метод
print(f'Hello, my name is {name}')
Person.say_hello('John') # вызов статического метода от класса
person = Person()
person.say_hello('John') # вызов статического метода от объекта
# Output:
# Hello, my name is John
# Hello, my name is JohnВ примере выше метод say_hello класса Person помечен декоратором @staticmethod. Он не принимает ссылку на объект или класс и просто выводит приветствие с именем. Таким образом, статический метод позволяет создавать функции, которые могут быть вызваны как от объекта, так и от класса.
Нажать, чтобы раскрыть
@property - это декоратор, который используется для определения свойства. Свойство позволяет управлять доступом к атрибутам объекта и выполнять дополнительные действия при их чтении и записи.
Пример использования @property:
class Person:
def __init__(self, name):
self._name = name
@property
def name(self): # свойство для чтения атрибута name
return self._name
@name.setter
def name(self, value): # свойство для записи атрибута name
self._name = value
person = Person('John') # создание объекта класса Person
print(person.name) # чтение атрибута name
person.name = 'Mike' # запись атрибута name
print(person.name) # чтение атрибута name
# Output:
# John
# MikeВ примере выше свойство name класса Person позволяет управлять доступом к атрибуту _name. Оно определено с помощью декораторов @property и @name.setter. Таким образом, свойство позволяет выполнять дополнительные действия при чтении и записи атрибута.
.setter - это декоратор, который определяет метод для записи атрибута. Он принимает первым параметром ссылку на свойство (name) и вторым параметром значение, которое нужно записать в атрибут. Таким образом, свойство позволяет управлять доступом к атрибутам объекта и выполнять дополнительные действия при их чтении и записи.
Нажать, чтобы раскрыть
**Магические методы** — это специальные методы в Python, имена которых начинаются и заканчиваются двумя подчёркиваниями: `__init__`, `__str__`, `__len__` и т.д. Интерпретатор не вызывает их напрямую, а делает это за вас при использовании соответствующего синтаксиса. Магические методы позволяют переопределять поведение стандартных операций для ваших объектов.Основные группы магических методов
-
Создание и инициализация объекта
-
__init__(self, ...)— инициализация экземпляра (заполняем атрибуты). -
__new__(cls, ...)— создание объекта (используется редко, в основном при наследовании от immutable-типов).
-
-
Человекочитаемое представление
-
__str__(self)— строка для пользователя (print(obj)). -
__repr__(self)— строка для разработчика / дебага (objв консоли,repr(obj)).
class User: def __init__(self, name): self.name = name def __repr__(self): return f"User(name={self.name!r})" def __str__(self): return self.name u = User("Elena") print(u) # Elena (__str__) print(repr(u)) # User(name='Elena') (__repr__)
-
-
Сравнение
-
__eq__(self, other)—== -
__ne__—!= -
__lt__,__le__,__gt__,__ge__—<,<=,>,>=
self.volume = volume def __lt__(self, other): return self.volume < other.volume print(Box(10) < Box(20)) # True ```
-
-
Коллекции и доступ по индексу
-
__len__(self)—len(obj) -
__getitem__(self, key)—obj[key] -
__setitem__(self, key, value)—obj[key] = value -
__iter__(self)— поддержкаfor/ генераторов
-
-
Операторы
-
__add__,__sub__,__mul__и т.д. — перегрузка+ - * / -
__contains__(self, item)— операторin
-
-
Контекстный менеджер
-
__enter__(self)и__exit__(self, exc_type, exc, tb)— работа сwith.
-
Нажать, чтобы раскрыть
Дата-классы - это классы, которые используются для представления данных. Они позволяют определить атрибуты и методы, которые будут у объектов этого класса. Дата-классы позволяют создавать объекты, которые содержат как данные, так и код, чтобы манипулировать данными.
Пример использования дата-классов:
from dataclasses import dataclass
@dataclass
class Person:
name: str
age: int
person = Person('John', 25) # создание объекта класса Person
print(person.name) # доступ к атрибуту name объекта
print(person.age) # доступ к атрибуту age объекта
# Output:
# John
# 25В примере выше дата-класс Person определен с помощью декоратора @dataclass. Он содержит два атрибута: name и age. Таким образом, дата-класс позволяет определить атрибуты и методы, которые будут у объектов этого класса.
Нажать, чтобы раскрыть
Enum - это перечисление, которое позволяет определить набор именованных констант. Он позволяет создавать набор значений, которые могут быть использованы в разных частях программы.
Пример использования Enum:
from enum import Enum
class Color(Enum):
RED = 1
GREEN = 2
BLUE = 3
print(Color.RED) # доступ к значению RED
print(Color.GREEN) # доступ к значению GREEN
print(Color.BLUE) # доступ к значению BLUE
# Output:
# Color.RED
# Color.GREEN
# Color.BLUEВ примере выше Enum Color определяет три именованных константы: RED, GREEN и BLUE. Таким образом, Enum позволяет определить набор именованных констант, где каждая константа имеет свое уникальное имя и значение.