Переменные (атрибуты) класса в Python

В этом уроке вы узнаете, как работают переменные (или атрибуты) класса в Python.

Содержание

Что такое переменные класса в Python?

Все в Python является объектом, включая класс. Другими словами, класс — это объект в Python.

Когда вы определяете класс с помощью ключевого слова class, Python создает объект с именем, таким же, как имя класса. Например:

class HtmlDocument:
   pass

В этом примере определяются класс HtmlDocument и объект HtmlDocument. Объект HtmlDocument имеет свойство __name__:

print(HtmlDocument.__name__) # HtmlDocument

И HTMLDocument имеет тип type:

print(type(HtmlDocument))  # <class 'type'>

Это также экземпляр класса type:

print(isinstance(HtmlDocument, type)) # True

Переменные класса привязаны к классу. Они являются общими для всех экземпляров этого класса.

В следующем примере переменные класса extension и version добавляются в класс HtmlDocument:

class HtmlDocument:
    extension = 'html'
    version = '5'

И extension, и version являются переменными класса HtmlDocument. Они привязаны к классу HtmlDocument.

Получение значений переменных класса

Чтобы получить значения переменных класса, вы используете точечную запись(.). Например:

print(HtmlDocument.extension) # html
print(HtmlDocument.version) # 5

Если вы обращаетесь к несуществующей переменной класса, то получите исключение AttributeError. Например:

HtmlDocument.media_type

Ошибка:

AttributeError: type object 'HtmlDocument' has no attribute 'media_type'

Другой способ получить значение переменной класса — использовать функцию getattr(). Функция getattr() принимает объект и имя переменной. Она возвращает значение переменной класса. Например:

extension = getattr(HtmlDocument, 'extension')
version = getattr(HtmlDocument, 'version')

print(extension)  # html
print(version)  # 5

Если переменная класса не существует, вы также получите исключение AttributeError. Чтобы избежать исключения, вы можете указать значение по умолчанию, если переменная класса не существует, например:

media_type = getattr(HtmlDocument, 'media_type', 'text/html')
print(media_type) # text/html

Установка значения для переменной класса

Чтобы установить значение переменной класса, вы используете точечную запись:

HtmlDocument.version = 10

или вы можете использовать встроенную функцию setattr():

setattr(HtmlDocument, 'version', 10)

Поскольку Python — динамический язык, вы можете добавить переменную класса в класс во время выполнения после его создания. Например, следующий код добавляет переменную класса media_type в класс HtmlDocument:

HtmlDocument.media_type = 'text/html'
print(HtmlDocument.media_type)

Аналогичным образом вы можете использовать функцию setattr():

setattr(HtmlDocument, media_type, 'text/html')
print(HtmlDocument.media_type)

Удаление

Чтобы удалить переменную класса во время выполнения, вы используете функцию delattr():

delattr(HtmlDocument, 'version')

Или вы можете использовать ключевое слово del:

del HtmlDocument.version

Хранение переменных классов

Python хранит переменные класса в атрибуте __dict__. __dict__ — это прокси-сервер сопоставления, который представляет собой словарь. Например:

from pprint import pprint


class HtmlDocument:
    extension = 'html'
    version = '5'


HtmlDocument.media_type = 'text/html'

pprint(HtmlDocument.__dict__)

Выход:

mappingproxy({'__dict__': <attribute '__dict__' of 'HtmlDocument' objects>,
              '__doc__': None,
              '__module__': '__main__',
              '__weakref__': <attribute '__weakref__' of 'HtmlDocument' objects>,
              'extension': 'html',
              'media_type': 'text/html',
              'version': '5'})

Как ясно показано в выводе, __dict__ имеет три переменные класса: extension, media_type и version, помимо других предопределенных переменных класса.

Python не позволяет вам изменять __dict__ напрямую. Например, следующее приведет к ошибке:

HtmlDocument.__dict__['released'] = 2008

Выход:

TypeError: 'mappingproxy' object does not support item assignment

Однако вы можете использовать функцию setattr() или запись через точку, чтобы косвенно изменить атрибут __dict__. Кроме того, ключом __dict__ являются строки, которые помогут Python ускорить поиск переменных.

Хотя Python позволяет получать доступ к переменным класса через словарь __dict__, это не очень хорошая практика. Кроме того, в некоторых ситуациях это не сработает. Например:

print(HtmlDocument.__dict__['type']) # BAD CODE

Атрибуты вызываемого класса

Атрибутами класса могут быть любые объекты, например функции.

Когда вы добавляете функцию в класс, она становится атрибутом класса. Поскольку функция является вызываемой, атрибут класса называется вызываемым атрибутом класса. Например:

from pprint import pprint


class HtmlDocument:
    extension = 'html'
    version = '5'

    def render():
        print('Rendering the Html doc...')


pprint(HtmlDocument.__dict__)

Выход:

mappingproxy({'__dict__': <attribute '__dict__' of 'HtmlDocument' objects>,
              '__doc__': None,
              '__module__': '__main__',
              '__weakref__': <attribute '__weakref__' of 'HtmlDocument' objects>,
              'extension': 'html',
              'render': <function HtmlDocument.render at 0x0000010710030310>,
              'version': '5'})
Rendering the Html doc...

В этом примере render является атрибутом класса HtmlDocument. Его значение является функцией.

Похожие посты
Добавить комментарий

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