-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathoop.py
More file actions
93 lines (93 loc) · 5.12 KB
/
oop.py
File metadata and controls
93 lines (93 loc) · 5.12 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
# Этап 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]