Атрибуты классов в Python — как использовать
В этом уроке вы узнаете об атрибутах класса в Python и о том, когда их правильно использовать.
- Что такое атрибуты класса в Python?
- Как работают атрибуты класса в Python
- Использование атрибутов класса
- 1) Хранение констант классов
- 2) Отслеживание данных во всех экземплярах
- 3) Определение значений по умолчанию
Что такое атрибуты класса в Python?
Начнем с простого класса Circle:
class Circle: def __init__(self, radius): self.pi = 3.14159 self.radius = radius def area(self): return self.pi * self.radius**2 def circumference(self): return 2*self.pi * self.radius
Класс Circle имеет два атрибута pi и radius. Он также имеет два метода расчета площади и окружности круга. И число pi, и радиус называются атрибутами экземпляра. Другими словами, они принадлежат конкретному экземпляру класса Circle. Если вы измените атрибуты экземпляра, это не повлияет на другие экземпляры.
Помимо атрибутов экземпляра, Python также поддерживает атрибуты классов. Атрибуты класса не связаны с каким-либо конкретным экземпляром класса. Но они являются общими для всех экземпляров класса.
Если вы программировали на Java или C#, вы увидите, что атрибуты класса похожи на статические члены, но не совпадают. Чтобы определить атрибут класса, вы помещаете его вне метода __init__().
Следующий пример определяет число pi как атрибут класса:
class Circle: pi = 3.14159 def __init__(self, radius): self.radius = radius def area(self): return self.pi * self.radius**2 def circumference(self): return 2 * self.pi * self.radius
После этого вы можете получить доступ к атрибуту класса через экземпляры класса или через имя класса:
object_name.class_attribute class_name.class_attribute
В методах area() и circumference() мы получаем доступ к атрибуту класса pi через переменную self.
Вне класса Circle вы можете получить доступ к атрибуту класса pi через экземпляр класса Circle или напрямую через класс Circle. Например:
c = Circle(10) print(c.pi) print(Circle.pi)
Выход:
3.14159 3.14159
Как работают атрибуты класса в Python
Когда вы получаете доступ к атрибуту через экземпляр класса, Python ищет атрибут в списке атрибутов экземпляра. Если в списке атрибутов экземпляра нет этого атрибута, Python продолжает его поиск в списке атрибутов класса. Python возвращает значение атрибута, если он находит его в списке атрибутов экземпляра или списке атрибутов класса.
Однако если вы получаете доступ к атрибуту, Python напрямую ищет его в списке атрибутов класса.
В следующем примере определяется класс Test, чтобы продемонстрировать, как Python обрабатывает атрибуты экземпляра и класса.
class Test: x = 10 def __init__(self): self.x = 20 test = Test() print(test.x) # 20 print(Test.x) # 10
Как это работает.
Класс Test имеет два атрибута с одинаковым именем(x): один является атрибутом экземпляра, а другой — атрибутом класса. Когда мы получаем доступ к атрибуту x через экземпляр класса Test, он возвращает 20, которое является переменной атрибута экземпляра.
Однако когда мы получаем доступ к атрибуту x через класс Test, он возвращает 10, что является значением атрибута класса x.
Использование атрибутов класса
Атрибуты класса полезны в некоторых случаях, например для хранения констант класса, отслеживания данных во всех экземплярах и определения значений по умолчанию.
1) Хранение констант классов
Поскольку константа не меняется от экземпляра класса к экземпляру, ее удобно хранить как атрибут класса. Например, класс Circle имеет константу pi, одинаковую для всех экземпляров класса. Следовательно, это хороший кандидат на роль атрибутов класса.
2) Отслеживание данных во всех экземплярах
Следующий пример добавляет атрибут класса Circle_list к классу Circle. Когда вы создаете новый экземпляр класса Circle, конструктор добавляет его в список:
class Circle: circle_list = [] pi = 3.14159 def __init__(self, radius): self.radius = radius # add the instance to the circle list self.circle_list.append(self) def area(self): return self.pi * self.radius**2 def circumference(self): return 2 * self.pi * self.radius c1 = Circle(10) c2 = Circle(20) print(len(Circle.circle_list)) # 2
3) Определение значений по умолчанию
Иногда вам нужно установить значение по умолчанию для всех экземпляров класса. В этом случае вы можете использовать атрибут класса.
В следующем примере определяется класс Product. Все экземпляры класса Product будут иметь скидку по умолчанию, указанную атрибутом класса default_discount:
class Product: default_discount = 0 def __init__(self, price): self.price = price self.discount = Product.default_discount def set_discount(self, discount): self.discount = discount def net_price(self): return self.price *(1 - self.discount) p1 = Product(100) print(p1.net_price()) # 100 p2 = Product(200) p2.set_discount(0.05) print(p2.net_price()) # 190