Второй аргумент super()
используется для двух целей:
Для предоставления упорядоченного списка классов для поиска;Порядок - это Порядок разрешения методов (MRO), и поиск атрибутов в super()
начинается с класса, следующего за именем, указанным в качестве первого аргумента для super()
Для привязки любогодескрипторы (например, методы).
Итак, super(clsobject, second_argument)
будет искать список __mro__
, затем искать clsobject
, затем продолжать поиск оставшейся части списка для атрибута.Вы хотели.Затем он использует протокол дескриптора 1020 * для привязки объекта к second_argument
.
Метод __new__
имеет смысл только для класса, поскольку он создает новый экземпляр;еще нет экземпляра, когда этот метод вызывается;именно фабрика должна создать экземпляр для этого класса.
Таким образом, вы не можете передать экземпляр в качестве второго аргумента.Вы можете передать только класс, и super()
может справиться с этим.Для случаев super()
смотрит на type(instance).__mro__
, но для классов вместо него используется classobject.__mro__
.Таким образом, передача cls
здесь вполне подходит.
__new__
также является статическим методом , что означает, что он игнорирует процесс привязки.Автоматическая передача первого аргумента, класса, не происходит.Вам нужно сделать это вручную, поэтому вызов ...__new__(cls)
.
Так что в этом конкретном случае строка:
cls.instance = super(Singleton, cls).__new__(cls)
будет искать Singleton
в cls.__mro__
, найтиследующий объект с атрибутом __new__
, а затем попытайтесь связать этот атрибут __new__
с cls
.Если вы не использовали множественное наследование, это будет object.__new__
.Метод __new__
является статическим, поэтому привязка не происходит, поэтому вы получаете object.__new__
, который затем вызывается с cls
в качестве первого аргумента.Это создает экземпляр класса Singleton
(или его подкласса), который затем присваивается атрибуту instance
объекта класса.