Переменные (атрибуты) класса в Python
В этом уроке вы узнаете, как работают переменные (или атрибуты) класса в 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. Его значение является функцией.