Налаштування створення класу

Оновлено: 28.04.2023

Щоразу, коли клас успадковує інший клас, __init_subclass__() викликається в батьківському класі. Таким чином можна писати класи, які змінюють поведінку підкласів. Це тісно пов’язане з декораторами класів, але де декоратори класів впливають лише на конкретний клас, до якого вони застосовані, __init_subclass__ застосовується виключно до майбутніх підкласів класу, що визначає метод.

classmethod object.__init_subclass__(cls) Цей метод викликається кожного разу, коли клас, що містить, є підкласом. Тоді cls є новим підкласом. Якщо визначено як звичайний метод екземпляра, цей метод неявно перетворюється на метод класу. Аргументи ключових слів, надані новому класу, передаються до батьківського класу __init_subclass__. Для сумісності з іншими класами, які використовують __init_subclass__, слід вилучити необхідні ключові аргументи та передати інші до базового класу, як у: class Philosopher: def __init_subclass__(cls, /, default_name, **kwargs): super().__init_subclass__(**kwargs) cls.default_name = default_name class AustralianPhilosopher(Philosopher, default_name="Bruce"): pass Реалізація за замовчуванням object.__init_subclass__ нічого не робить, але викликає помилку, якщо вона викликається з будь-якими аргументами. Примітка Підказка метакласу metaclass споживається рештою механізму типів і ніколи не передається реалізаціям __init_subclass__. Фактичний метаклас (а не явна підказка) можна отримати як type(cls). Нове в версії 3.6.

class Philosopher:
    def __init_subclass__(cls, /, default_name, **kwargs):
        super().__init_subclass__(**kwargs)
        cls.default_name = default_name

class AustralianPhilosopher(Philosopher, default_name="Bruce"):
    pass

Коли клас створюється, type.__new__() сканує змінні класу та виконує зворотні виклики до тих, що мають хук __set_name__().

object.__set_name__(self, owner, name) Автоматично викликається під час створення класу власника owner. Об’єкту було призначено name у цьому класі: class A: x = C() # Automatically calls: x.__set_name__(A, 'x') Якщо змінна класу призначається після створення класу, __set_name__() не буде викликатися автоматично. За потреби __set_name__() можна викликати безпосередньо: class A: pass c = C() A.x = c # The hook is not called c.__set_name__(A, 'x') # Manually invoke the hook Дивіться Створення об’єкта класу для отримання додаткової інформації. Нове в версії 3.6.

class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
class A:
   pass

c = C()
A.x = c                  # The hook is not called
c.__set_name__(A, 'x')   # Manually invoke the hook
class Meta(type):
    pass

class MyClass(metaclass=Meta):
    pass

class MySubclass(MyClass):
    pass