Атрибуты классов в Python — как использовать

В этом уроке вы узнаете об атрибутах класса в Python и о том, когда их правильно использовать.

Содержание

Что такое атрибуты класса в 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
Похожие посты
Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *