Как именно inspect.signature работает с классами? - PullRequest
6 голосов
/ 29 мая 2019

В документе inspect.signature указано, что он поддерживает классы в качестве входных данных, но он не вдавался в подробности:

Принимает широкий спектр вызываемых в Pythonот простых функций и классов до functools.partial() объектов.

Если я вызываю inspect.signature(MyClass), какую подпись он возвращает?Возвращает ли подпись MyClass.__init__?Или MyClass.__new__?Или что-то еще?

1 Ответ

10 голосов
/ 29 мая 2019

Он пытается почти все, что мог.Я думаю, что детали, вероятно, намеренно недокументированы, потому что они сложны и, вероятно, получат больше, так как новые версии Python добавляют больше материала для проб.

Например, в CPython 3.7.3, Путь к коду выполняет следующие действия по порядку:

  • Если метакласс имеет пользовательский __call__, определенный в Python, он использует сигнатуру метакласса __call__ с удаленным первым аргументом.
  • В противном случае, если у класса есть метод __new__, определенный в Python, он использует сигнатуру __new__ с удаленным первым аргументом.
  • В противном случае, если у класса есть __init__метод, определенный в Python, он использует подпись __init__ с первым удаленным аргументом.
  • В противном случае он пересекает MRO, ища __text_signature__.Если он находит его, он анализирует __text_signature__, чтобы получить информацию о подписи.
  • Если он все еще ничего не нашел, если тип __init__ равен object.__init__, а тип __new__ равен object.__new__ возвращает подпись класса object.(Вокруг этого пункта есть вводящий в заблуждение комментарий и возможная ошибка, связанная с метаклассами - в комментарии говорится, что он проверяет type.__init__, но этого не происходит. Я думаю, этот коммит , возможно, допустил ошибкуздесь.)
  • Если он все еще ничего не нашел, он сдается и поднимает ValueError, говоря, что ничего не может найти.
...