-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathoop_notebook.py
More file actions
136 lines (90 loc) · 5.28 KB
/
oop_notebook.py
File metadata and controls
136 lines (90 loc) · 5.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# # Основы объектно-ориентированного программирования в Python
#
# Этот notebook содержит пошаговое введение в работу с классами в Python.
# ## Этап 1: Объявление класса и интроспекция (Видео №1)
#
# Класс создается ключевым словом `class`, а его название пишется в стиле CamelCase. Даже пустой класс является объектом и имеет встроенные атрибуты.
# 1. Создание простейшего класса
class Person:
pass
# 2. Интроспекция класса
print(Person.__name__) # Имя класса [2]
print(dir(Person)) # Список всех атрибутов и методов [2]
# 3. Создание экземпляра
p = Person()
print(type(p)) # Тип объекта [2]
print(id(p)) # Адрес объекта в памяти [3]
# 4. Динамическое создание объекта того же типа
new_p = type(p)()
print(id(new_p)) # Разные ID подтверждают, что это разные объекты [3]
# ## Этап 2: Атрибуты класса и функции управления (Видео №2)
#
# Атрибуты класса задаются через простое присваивание и хранятся в специальном словаре `__dict__`.
class Person:
name = "Ivan" # Атрибут класса [4]
# 1. Работа с пространством имен (mappingproxy)
print(Person.__dict__) # [5]
# 2. Динамическое добавление атрибута
Person.age = 25 # [6]
# 3. Встроенные функции для работы с атрибутами
setattr(Person, "dob", "2000-01-01") # Установка [7]
print(getattr(Person, "name")) # Чтение [7]
delattr(Person, "dob") # Удаление [7]
# ## Этап 3: Экземпляры и локальные пространства имен (Видео №3)
#
# При вызове класса создается экземпляр с собственным пустым словарем `__dict__`.
p1 = Person()
p2 = Person()
# 1. Поиск атрибута (сначала в экземпляре, потом в классе)
print(p1.name) # Вернет "Ivan" из класса, так как в p1.__dict__ пусто [9]
# +
# 2. Создание уникального состояния экземпляра
p1.name = "Oleg"
p2.name = "Dima"
p2.age = 20
print(p1.__dict__) # {'name': 'Oleg'} [10]
print(p2.__dict__) # {'name': 'Dima', 'age': 20} [10, 11]
# -
# ## Этап 4: Методы экземпляра и параметр self (Видео №4)
#
# Функции внутри класса при вызове через экземпляр становятся «связанными методами» и автоматически получают ссылку на объект в первом аргументе (`self`).
class Person:
def hello(self): # self — обязательный параметр для метода экземпляра [13, 15]
print(f"Hello! Я объект {id(self)}") # [14]
# +
p = Person()
# 1. Вызов через точку (синтаксический сахар)
p.hello() # Ссылка на 'p' передается в 'self' автоматически [14, 16]
# -
# 2. Явный вызов через класс (что происходит под капотом)
Person.hello(p) # [16, 17]
# ## Этап 5: Инициализация через __init__ (Видео №5)
#
# Метод `__init__` вызывается автоматически сразу после создания объекта для задания его начальных свойств.
class Person:
def __init__(self, name, age): # Метод-инициализатор [18, 20]
self.name = name # Запись данных в локальный словарь объекта [21, 22]
self.age = age
def display(self):
print(f"Имя: {self.name}, Возраст: {self.age}") # [23]
# +
# Создание проинициализированных объектов
p1 = Person("Ivan", 25) # [18]
p2 = Person("Oleg", 30) # [18]
p1.display()
# -
# ## Этап 6: Статические методы (Видео №6)
#
# Статические методы не привязаны к конкретному экземпляру и не принимают `self`. Они определяются декоратором `@staticmethod`.
class Person:
def __init__(self, name):
self.name = name
@staticmethod
def generic_info(): # Не принимает self [24, 28]
print("Это вспомогательный метод класса Person.") # [25, 28]
# 1. Вызов статического метода (можно через класс или через объект)
Person.generic_info() # [28]
p = Person("Dima")
p.generic_info() # [28]
# 2. Проверка: статический метод — это один и тот же объект для всех экземпляров
print(id(Person.generic_info) == id(p.generic_info)) # True [29]