В чем разница между статическими и динамическими атрибутами класса?

Опубликован: 03.08.2024 67

Атрибуты класса (объекта) в Python можно условно разделить на две группы:

  • статические (поля класса), которые объявляются внутри тела класса и создаются тогда, когда создается класс;
  • динамические (поля экземпляра класса), для создания которых необходимо обратиться к self внутри метода класса.

Разница между ними в том, что для работы со статическим атрибутом не нужно создавать экземпляр класса, а для работы с динамическим – нужно.

# создание статических и динамических атрибутов класса
class Rectangle:
    default_color = "green"     # статический атрибут default_color

    def __init__(self, width, height):
        self.width = width       # динамические атрибуты width и height
        self.height = height

# доступ к статическим атрибутам напрямую через указание класса
Rectangle.default_color
'green'

# доступ к динамическим атрибутам через создание экземпляра класса
rect = Rectangle(10, 20)
rect.width
10
rect.height
20

Если обратиться к динамическому атрибуту через класс, то получим ошибку:

Rectangle.width
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: type object 'Rectangle' has no attribute 'width'

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

Если поменять статический атрибут через экземпляр класса, то у экземпляра будет создан атрибут с таким же именем как статический, а доступ к последнему будет потерян:

# присвоим атрибуту default_color новое значение
Rectangle.default_color = "red"
Rectangle.default_color
'red'

# cоздадим два объекта класса Rectangle и проверим, что default_color у них совпадает
r1 = Rectangle(5, 15)
r2 = Rectangle(10, 20)

r1.default_color
'red'
r2.default_color
'red'

# меняем атрибут default_color через r1
r1.default_color = "blue"
r1.default_color
'blue'

# при этом у r2 остается старое значение статического атрибута
r2.default_color
'red'
Rectangle.default_color
'red'

Вообще лучше напрямую с атрибутами не работать, а использовать для этого свойства класса (property). Важным преимуществом работы через свойства является то, что вы можете осуществлять проверку входных значений, перед тем как присвоить их атрибутам.

Похожие посты

Что такое метакласс в Python?

В чем разница между методами экземпляра, методами класса и статическими методами в Python?

Что такое дескрипторы в Python?

Как создать класс и объект класса в Python

Комментариев нет.