Что делает super (подкласс, класс) .__ new __ (класс)? - PullRequest
0 голосов
/ 07 мая 2018

В следующей Python реализации шаблона Singleton :

class Singleton(object):
    def __new__(cls):
        if not hasattr(cls, 'instance'):
            cls.instance = super(Singleton, cls).__new__(cls)
        return cls.instance

Что делает строка cls.instance = super(Singleton, cls).__new__(cls)?

Среди прочего в этой строке я не понимаю, что такое super. Я видел использование super с (subclass, instance), но здесь мы передаем его (subclass, class). Так будут ли аргументы (Singleton class, Singleton class)?

Живой пример

1 Ответ

0 голосов
/ 07 мая 2018

Второй аргумент 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 объекта класса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...