|
||||||||||
Создание классов
Время создания: 09.11.2021 23:11
Автор: alensav
Текстовые метки: Создание классов
Раздел: PYTHON
Запись: alensav/MyTetra2/main/base/1636488665dq1xzt3lk2/text.html на raw.githubusercontent.com
|
||||||||||
|
||||||||||
Python — объектно-ориентированный язык с начала его существования. Поэтому, создание и использование классов и объектов в Python просто и легко. Эта статья поможет разобраться на примерах в области поддержки объектно-ориентированного программирования Python. Если у вас нет опыта работы с объектно-ориентированным программированием (OOП), ознакомьтесь с вводным курсом или учебным пособием, чтобы понять основные понятия. Оператор class создает новое определение класса. Имя класса сразу следует за ключевым словом class, после которого ставиться двоеточие: class ClassName:
"""Необязательная строка документации класса"""
class_suite
Пример создания класса на Python: Копировать class Employee:
"""Базовый класс для всех сотрудников"""
emp_count = 0
def __init__(self, name, salary):
self.name = name
self.salary = salary
Employee.emp_count += 1
def display_count(self):
print('Всего сотрудников: %d' % Employee.empCount)
def display_employee(self):
print('Имя: {}. Зарплата: {}'.format(self.name, self.salary))
Чтобы создать экземпляры классов, нужно вызвать класс с использованием его имени и передать аргументы, которые принимает метод __init__. Копировать # Это создаст первый объект класса Employee
emp1 = Employee("Андрей", 2000)
# Это создаст второй объект класса Employee
emp2 = Employee("Мария", 5000)
Получите доступ к атрибутам класса, используя оператор . после объекта класса. Доступ к классу можно получить используя имя переменой класса: Копировать emp1.display_employee()
emp2.display_employee()
print("Всего сотрудников: %d" % Employee.emp_count)
Теперь, систематизируем все. Копировать class Employee:
"""Базовый класс для всех сотрудников"""
emp_count = 0
def __init__(self, name, salary):
self.name = name
self.salary = salary
Employee.emp_count += 1
def display_count(self):
print('Всего сотрудников: %d' % Employee.emp_count)
def display_employee(self):
print('Имя: {}. Зарплата: {}'.format(self.name, self.salary))
# Это создаст первый объект класса Employee
emp1 = Employee("Андрей", 2000)
# Это создаст второй объект класса Employee
emp2 = Employee("Мария", 5000)
emp1.display_employee()
emp2.display_employee()
print("Всего сотрудников: %d" % Employee.emp_count)
При выполнении этого кода, мы получаем следующий результат: Имя: Андрей. Зарплата: 2000
Имя: Мария. Зарплата: 5000
Всего сотрудников: 2
Вы можете добавлять, удалять или изменять атрибуты классов и объектов в любой момент. Копировать emp1.age = 7 # Добавит атрибут 'age'
emp1.age = 8 # Изменит атрибут 'age'
del emp1.age # Удалит атрибут 'age'
Вместо использования привычных операторов для доступа к атрибутам вы можете использовать эти функции:
Копировать hasattr(emp1, 'age') # возвращает true если атрибут 'age' существует
getattr(emp1, 'age') # возвращает значение атрибута 'age'
setattr(emp1, 'age', 8) #устанавливает атрибут 'age' на 8
delattr(empl, 'age') # удаляет атрибут 'age'
Каждый класс Python хранит встроенные атрибуты, и предоставляет к ним доступ через оператор ., как и любой другой атрибут:
Для вышеуказанного класса давайте попробуем получить доступ ко всем этим атрибутам: Копировать class Employee:
"""Базовый класс для всех сотрудников"""
emp_count = 0
def __init__(self, name, salary):
self.name = name
self.salary = salary
Employee.empCount += 1
def display_count(self):
print('Всего сотрудников: %d' % Employee.empCount)
def display_employee(self):
print('Имя: {}. Зарплата: {}'.format(self.name, self.salary))
print("Employee.__doc__:", Employee.__doc__)
print("Employee.__name__:", Employee.__name__)
print("Employee.__module__:", Employee.__module__)
print("Employee.__bases__:", Employee.__bases__)
print("Employee.__dict__:", Employee.__dict__)
Когда этот код выполняется, он возвращает такой результат: Employee.__doc__: Базовый класс для всех сотрудников
Employee.__name__: Employee
Employee.__module__: __main__
Employee.__bases__: (<class 'object'>,)
Employee.__dict__: {'__module__': '__main__', '__doc__': 'Базовый класс для всех сотрудников', 'emp_count': 0, '__init__': <function Employee.__init__ at 0x03C7D7C8>, 'display_count': <function Employee.display_count at 0x03FA6AE0>, 'display_employee': <function Employee.display_employee at 0x03FA6B28>, '__dict__': <attribute '__dict__' of 'Employee' objects>, '__weakref__': <attribute '__weakref__' of 'Employee' objects>}
Удаление объектов (сбор мусора) Python автоматически удаляет ненужные объекты (встроенные типы или экземпляры классов), чтобы освободить пространство памяти. С помощью процесса ‘Garbage Collection’ Python периодически восстанавливает блоки памяти, которые больше не используются. Сборщик мусора Python запускается во время выполнения программы и тогда, когда количество ссылок на объект достигает нуля. С изменением количества обращений к нему, меняется количество ссылок. Когда объект присваивают новой переменной или добавляют в контейнер (список, кортеж, словарь), количество ссылок объекта увеличивается. Количество ссылок на объект уменьшается, когда он удаляется с помощью del, или его ссылка выходит за пределы видимости. Когда количество ссылок достигает нуля, Python автоматически собирает его. Копировать a = 40 # создали объект <40>
b = a # увеличивает количество ссылок <40>
c = [b] # увеличивает количество ссылок <40>
del a # уменьшает количество ссылок <40>
b = 100 # уменьшает количество ссылок <40>
c[0] = -1 # уменьшает количество ссылок <40>
Обычно вы не заметите, когда сборщик мусора уничтожает экземпляр и очищает свое пространство. Но классом можно реализовать специальный метод __del__(), называемый деструктором. Он вызывается, перед уничтожением экземпляра. Этот метод может использоваться для очистки любых ресурсов памяти. Пример работы __del__() Копировать class Point:
def __init__(self, x=0, y=0):
self.x = x
self.y = y
def __del__(self):
class_name = self.__class__.__name__
print('{} уничтожен'.format(class_name))
pt1 = Point()
pt2 = pt1
pt3 = pt1
print(id(pt1), id(pt2), id(pt3)) # выведите id объектов
del pt1
del pt2
del pt3
Когда вышеуказанный код выполняется и выводит следующее: 17692784 17692784 17692784
Point уничтожен
В идеале вы должны создавать свои классы в отдельном модуле. Затем импортировать их в основной модуль программы с помощью import SomeClass. Наследование — это процесс, когда один класс наследует атрибуты и методы другого. Класс, чьи свойства и методы наследуются, называют Родителем или Суперклассом. А класс, свойства которого наследуются — класс-потомок или Подкласс. Вместо того, чтобы начинать с нуля, вы можете создать класс, на основе уже существующего. Укажите родительский класс в круглых скобках после имени нового класса. Класс наследник наследует атрибуты своего родительского класса. Вы можете использовать эти атрибуты так, как будто они определены в классе наследнике. Он может переопределять элементы данных и методы родителя. Классы наследники объявляются так, как и родительские классы. Только, список наследуемых классов, указан после имени класса. class SubClassName(ParentClass1[, ParentClass2, ...]):
"""Необязательная строка документации класса"""
class_suite
Пример наследования класса в Python Копировать class Parent: # объявляем родительский класс
parent_attr = 100
def __init__(self):
print('Вызов родительского конструктора')
def parent_method(self):
print('Вызов родительского метода')
def set_attr(self, attr):
Parent.parent_attr = attr
def get_attr(self):
print('Атрибут родителя: {}'.format(Parent.parent_attr))
class Child(Parent): # объявляем класс наследник
def __init__(self):
print('Вызов конструктора класса наследника')
def child_method(self):
print('Вызов метода класса наследника')
c = Child() # экземпляр класса Child
c.child_method() # вызов метода child_method
c.parent_method() # вызов родительского метода parent_method
c.set_attr(200) # еще раз вызов родительского метода
c.get_attr() # снова вызов родительского метода
Когда этот код выполняется, он выводит следующий результат: Вызов конструктора класса наследника
Вызов метода класса наследника
Вызов родительского метода
Атрибут родителя: 200
Аналогичным образом вы можете управлять классом с помощью нескольких родительских классов: class A: # объявите класс A
...
class B: # объявите класс B
...
class C(A, B): # C наследуется от A и B
...
Вы можете использовать функции issubclass() или isinstance() для проверки отношений двух классов и экземпляров.
Вы всегда можете переопределить методы родительского класса. В вашем подклассе могут понадобиться специальные функции. Это одна из причин переопределения родительских методов. Пример переопределения методов: Копировать class Parent: # объявите родительский класс
def my_method(self):
print('Вызов родительского метода')
class Child(Parent): # объявите класс наследник
def my_method(self):
print('Вызов метода наследника')
c = Child() # экземпляр класса Child
c.my_method() # метод переопределен классом наследником
Когда этот код выполняется, он производит следующий результат: Вызов метода наследника
В данной таблице перечислены некоторые общие функции. Вы можете переопределить их в своих собственных классах.
Предположим, вы создали класс Vector для представления двумерных векторов. Что происходит, когда вы используете дополнительный оператор для их добавления? Скорее всего, Python будет против. Однако вы можете определить метод __add__ в своем классе для добавления векторов и оператор + будет вести себя так как нужно. Копировать class Vector:
def __init__(self, a, b):
self.a = a
self.b = b
def __str__(self):
return 'Vector ({}, {})'.format(self.a, self.b)
def __add__(self, other):
return Vector(self.a + other.a, self.b + other.b)
v1 = Vector(2, 10)
v2 = Vector(5, -2)
print(v1 + v2)
При выполнении этого кода, мы получим: Vector(7, 8)
Атрибуты класса могут быть не видимыми вне определения класса. Вам нужно указать атрибуты с __ вначале, и эти атрибуты не будут вызваны вне класса. Пример приватного атрибута: Копировать class JustCounter:
__secret_count = 0
def count(self):
self.__secret_count += 1
print(self.__secret_count)
counter = JustCounter()
counter.count()
counter.count()
print(counter.__secret_count)
При выполнении данного кода, имеем следующий результат: 1
2
Traceback (most recent call last):
File "test.py", line 12, in <module>
print(counter.__secret_count)
AttributeError: 'JustCounter' object has no attribute '__secret_count'
Вы можете получить доступ к таким атрибутам, так object._className__attrName. Если вы замените свою последнюю строку следующим образом, то она будет работать. Копировать ...
print(counter._JustCounter__secret_count)
При выполнении кода, получаем результат: 1
2
2
Какое их представленных слов лучше всего подходит для названия класса? Параметры функции range могут быть отрицательными целыми числами |
||||||||||
Прикрепленные файлы:
|
||||||||||
Так же в этом разделе:
|
||||||||||
|
||||||||||
|