Визначення класів

Оновлено: 24.04.2023

Визначення класу визначає об’єкт класу (див. розділ Стандартна ієрархія типів):

classdef    ::=  [decorators] "class" classname [inheritance] ":" suite
inheritance ::=  "(" [argument_list] ")"
classname   ::=  identifier

Визначення класу є виконуваним оператором. Список успадкування зазвичай надає список базових класів (див. Метакласи для більш просунутого використання), тому кожен елемент у списку повинен оцінюватися як об’єкт класу, який дозволяє створювати підкласи. Класи без списку успадкування успадковують, за замовчуванням, від базового класу object; отже,

class Foo:
    pass

еквівалентно

class Foo(object):
    pass

Потім набір класів виконується в новому фреймі виконання (див. Називання та зв’язування), використовуючи щойно створений локальний простір імен і оригінальний глобальний простір імен. (Зазвичай набір містить в основному визначення функцій.) Коли набір класу завершує виконання, його кадр виконання відкидається, але його локальний простір імен зберігається. 5 Потім створюється об’єкт класу з використанням списку успадкування для базових класів і збереженого локального простору імен для словника атрибутів. Ім’я класу прив’язане до цього об’єкта класу в оригінальному локальному просторі імен.

Порядок, у якому атрибути визначені в тілі класу, зберігається в __dict__ нового класу. Зауважте, що це надійно лише відразу після створення класу та лише для класів, які були визначені за допомогою синтаксису визначення.

Створення класів можна значно налаштувати за допомогою metaclasses.

Класи також можна декорувати: як і при декоруванні функцій,

@f1(arg)
@f2
class Foo: pass

приблизно еквівалентно

class Foo: pass
Foo = f1(arg)(f2(Foo))

Правила оцінки для виразів декоратора такі ж, як і для декораторів функцій. Потім результат прив’язується до імені класу.

Примітка програміста: Змінні, визначені у визначенні класу, є атрибутами класу; їх ділять інстанції. Атрибути екземпляра можна встановити в методі за допомогою self.name = value. Як атрибути класу, так і атрибути екземпляра доступні через нотацію «self.name», а атрибут екземпляра приховує атрибут класу з таким самим іменем, коли до нього звертаються таким чином. Атрибути класу можна використовувати як значення за замовчуванням для атрибутів екземплярів, але використання там змінних значень може призвести до неочікуваних результатів. Дескриптори можна використовувати для створення змінних екземпляра з різними деталями реалізації.