Атрибуты классов и статические методы

Последнее обновление: 28.03.2024

Атрибуты класса

Кроме атрибутов объектов в классе можно определять атрибуты классов. Подобные атрибуты определяются в виде переменных уровня класса. Например:

class Person:
     type = "Person"
     description = "Describes a person"


print(Person.type)          # Person
print(Person.description)   # Describes a person

Person.type = "Class Person"
print(Person.type)          # Class Person

Здесь в классе Person определено два атрибута: type, который хранит имя класса, и description, который хранит описание класса.

Для обращения к атрибутам класса мы можем использовать имя класса, например: Person.type, и, как и атрибуты объекта, мы можем получать и изменять их значения.

Подобные атрибуты являются общими для всех объектов класса:

class Person:
     type = "Person"
     def __init__(self, name):
         self.name = name


tom = Person("Tom")
bob = Person("Bob")
print(tom.type)     # Person
print(bob.type)     # Person

# изменим атрибут класса
Person.type = "Class Person"
print(tom.type)     # Class Person
print(bob.type)     # Class Person

Атрибуты класса могут применяться для таких ситуаций, когда нам надо определить некоторые общие данные для всех объектов. Например:

class Person:
    default_name = "Undefined"

    def __init__(self, name):
        if name:
            self.name = name
        else:
            self.name = Person.default_name


tom = Person("Tom")
bob = Person("")
print(tom.name)  # Tom
print(bob.name)  # Undefined

В данном случае атрибут default_name хранит имя по умолчанию. И если в конструктор передана пустая строка для имени, то атрибуту name передается значение атрибута класса default_name. Для обращения к атрибуту класса внутри методов можно применять имя класса

self.name = Person.default_name

Атрибут класса

Возможна ситуация, когда атрибут класса и атрибут объекта совпадает по имени. Если в коде для атрибута объекта не задано значение, то для него может применяться значение атрибута класса:

class Person:
    name = "Undefined"

    def print_name(self):
        print(self.name)


tom = Person()
bob = Person()
tom.print_name()    # Undefined
bob.print_name()    # Undefined

bob.name = "Bob"
bob.print_name()    # Bob
tom.print_name()    # Undefined

Здесь метод print_name использует атрибут объект name, однако нигде в коде этот атрибут не устанавливается. Зато на уровне класса задан атрибут name. Поэтому при первом обращении к методу print_name, в нем будет использоваться значение атрибута класса:

tom = Person()
bob = Person()
tom.print_name()    # Undefined
bob.print_name()    # Undefined

Однако далее мы можем поменять установить атрибут объекта:

bob.name = "Bob"
bob.print_name()    # Bob
tom.print_name()    # Undefined

Причем второй объект - tom продолжит использовать атрибут класса. И если мы изменим атрибут класса, соответственно значение tom.name тоже изменится:

tom = Person()
bob = Person()
tom.print_name()    # Undefined
bob.print_name()    # Undefined

Person.name = "Some Person"     # меняем значение атрибута класса
bob.name = "Bob"                # устанавливаем атрибут объекта
bob.print_name()    # Bob
tom.print_name()    # Some Person

Статические методы

Кроме обычных методов класс может определять статические методы. Такие методы предваряются аннотацией @staticmethod и относятся в целом к классу. Статические методы обычно определяют поведение, которое не зависит от конкретного объекта:

class Person:
    __type = "Person"

    @staticmethod
    def print_type():
        print(Person.__type)


Person.print_type()     # Person - обращение к статическому методу через имя класса

tom = Person()
tom.print_type()     # Person - обращение к статическому методу через имя объекта

В данном случае в классе Person определен атрибут класса __type, который хранит значение, общее для всего класса - название класса. Причем поскольку название атрибута предваряется двумя подчеркиваниями, то данный атрибут будет приватным, что защитит от недопустимого изменения.

Также в классе Person определен статический метод print_type, который выводит на консоль значение атрибута __type. Действие этого метода не зависит от конкретного объекта и относится в целом ко всему классу - вне зависимости от объекта на консоль будет выводится одно и то же значение атрибута __type. Поэтому такой метод можно сделать статическим.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850