Назначение внутри списка базовых классов - PullRequest
0 голосов
/ 15 февраля 2019

При чтении источника модуля typing я заметил следующее:

class _SpecialForm(_Final, _Immutable, _root=True):
    ...

Здесь назначение находится внутри списка базовых классов.

Позже оно проверяется:

class _Final:
    def __init_subclass__(self, *args, **kwds):
        if '_root' not in kwds:
            raise TypeError("Cannot subclass special typing classes")

Где именно заканчивается _root?Документы называют его «аргументами ключевого слова класса» (https://docs.python.org/3/reference/datamodel.html#object.init_subclass),, но я не смог найти дополнительную информацию по этому вопросу.

1 Ответ

0 голосов
/ 16 февраля 2019

Аргумент ключевого слова класса - это любой аргумент kwyword, который передается в объявлении класса.Только один такой аргумент имеет специальную обработку - metaclass= - этот диктует вызываемую функцию, которая будет использоваться для предоставления метакласса.

Любой другой аргумент ключевого слова, переданный метаклассу __new__ и * как есть.Методы 1005 * и любой метод суперкласса __init_subclass__.Они не обрабатываются особым образом и, прежде всего, не являются «базовыми классами» - упомянутые выше методы обычно получают эти ключевые аргументы как любой метод Python: они могут быть объявлены в сигнатуре метода или могут принять**kwargs словарь (что имеет место).

Стоит отметить, что при передаче таких аргументов с помощью надлежащего метода __init_subclass__ в суперклассах, которые его "проглотят", объявление класса завершится неудачно с TypeError из-за нераспознанного аргумента object __init_subclass__.Напротив, реализация метакласса по умолчанию __new__ и __init__ в классе type будет просто игнорировать любые переданные дополнительные ключевые слова.

Таким образом:

In [1]: class A(test=None): 
   ...:     pass 
   ...:            

завершается неудачно с:

TypeError: __init_subclass__() takes no keyword arguments

Пока:

In [2]: class A: 
   ...:     def __init_subclass__(cls, **kwd): 
   ...:         super().__init_subclass__(cls)
   ...:                                                                                 

In [3]: class B(A, test=None): 
   ...:     pass 
   ...:           

работает без проблем.(A.__init_subclass__ Квадрат будет передан {"test": None})

...