В чем разница между параметрами в super и скобками init .... super () .__ init __ () - PullRequest
0 голосов
/ 25 мая 2018

Я понимаю, что концепция super().__init__() связана с наследованием, и я видел код с параметрами в init.Однако я наткнулся на пример кода, который имел такой код:

class Maze(tk.Tk, object):
    def __init__(self):
        super(Maze, self).__init__()

параметры теперь находятся в скобках super.В чем разница и почему один может быть использован над другим?Спасибо

1 Ответ

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

Это оригинальный способ super(), предназначенный для работы:

super(Maze, self).__init__()

Это также единственный способ, которым он работал в Python 2.

Итак, почему аргументы?

Вы хотите вызвать __init__() класса, который является супер классом, если Maze (вероятно, tk.Tk), привязанный к self.Для этого вам нужно передать аргументы Maze и self super, чтобы он знал, что делать.

Что он на самом деле делает?

super(Maze, self).__init__ должен определить type(self) для извлечения MRO из него, т.е. порядок, в котором классы наследуются друг от друга.

Затем в этом списке он находит класс, которыйчуть выше Maze и ищет __init__ в этом классе или любом классе над ним.Когда он находит его, он ограничивает метод __init__ init self (т.е. фиксирует свой первый аргумент, поэтому вам не нужно его передавать).

Вы можете реализовать эту версию superсам.Это будет примерно так:

class my_super:
    def __init__(self, cls, obj):
        self.cls = cls
        self.obj = obj

    def __getattribute__(self, method_name):
        cls = object.__getattribute__(self, 'cls')
        obj = object.__getattribute__(self, 'obj')
        mro = type(obj).__mro__
        mro_above_cls = mro[mro.index(cls)+1:]
        for super_cls in mro_above_cls:
            if hasattr(super_cls, method_name):
                method = getattr(super_cls, method_name)
                return functools.partial(method, self)

Обратите внимание, что вам не нужно вызывать это из метода вообще.Вы можете сделать это:

class A:
    def f(self):
        print('A')


class B(A):
    def f(self):
        print('B')

a = A()
b = B()

super(B, b).f()      # prints: A
my_super(B, b).f()   # prints: A

А как насчет версии без аргументов?

super(Maze, self).__init__() была очень явной, но почти весь код Python всегда использовал текущий класс и self в качестве аргументов, поэтомуPython 3 упростил задачу, предоставив магию super(), которая знает, чего вы хотите.

...