Наследование аргументов ключевого слова с помощью super (), но они не перечислены, пока не будут указаны при создании экземпляра - PullRequest
1 голос
/ 11 апреля 2019

Мне трудно понять это, я думаю, довольно простая концепция. Я создаю какое-то приложение tkinter (не актуально) и играю с наследующими атрибутами через super и * args, ** kwargs:

class MainApp():

    def __init__(self, master = None, y = 10, x = "sample string"):
        self.master = master  
        self.y = y
        self.x = x
    # master is in the end root = tk.Tk(), 
    # which i pass as argument when creating that object, y and x are just for testing purpose

class Replica(MainApp):
    def __init__(self, *args, **kw):
        super().__init__(*args, **kw)
        print(args)
        print(kw)
    # This is also just for testing how this stuff works, thing is;
    # When I run following code:


root = tk.Tk()
app = Replica(root)
print (app.x, app.y) # this returns ~ sample string 10; as expected
root.mainloop()

#But when output of print(args, kwargs) in Replica class __init__ method,
#it returns only (<tkinter.Tk object .>,) in printing args and empty dic
#{} in kwargs, therefore x and y werent considered either args or kwargs
# WHY?


#Well, but if i initialize Replica like this:

root = tk.Tk()
app = Replica(master = root, y = 5, x = "changed string")
root.mainloop()
# It returns empty tuple for args (), and full kwarg dic like this:
{'master': <tkinter.Tk object .>, 'y': 2, 'x': 'changed string'}

# In same logic, if I initiate Replica like this:


app = Replica(root, 10, "changed string")
# This returns all attributes in args, therefore print(args) in __init__
# method returns (<tkinter.Tk object .>, 10, 'changed string') 
# and kwargs are empty {}

# Similiarly, when running this:
app = Replica(root, 10, x = "changed string")
# It shifts x to kwargs dictionary and return is
# (<tkinter.Tk object .>, 10) and {'x': 'changed string'}

Я имею в виду, я вроде понимаю, что происходит, я не слепой, но все еще удивляюсь, почему master, y и x не наследуются как kwargs сразу, в конце концов, они являются аргументами ключевых слов в MainApp init метод. Я предполагаю, что метод super () позаботится об этом. Приложение работает нормально, но я разочарован тем, что не понял этого, и был бы признателен за понимание.

Как наследуются атрибуты x и y, когда ..

def __init__(self, *args, **kwargs)
    super().__init__(*args, **kwargs) 

.. не указывает x или y. И даже когда это работает:

def __init__(self, master):
    super().__init__(master)

Работает нормально и наследует атрибуты x и y ..

Еще раз, я был бы признателен за понимание, спасибо.

1 Ответ

1 голос
/ 11 апреля 2019

Это не имеет ничего общего с super или наследованием.Это просто параметры, принимающие значения по умолчанию, когда аргументы не передаются.Вот простой пример:

def foo(x=5):
  print('foo: x =', x)

def bar(*args, **kwargs):
  print('bar:', args, kwargs)
  foo(**kwargs)

bar()
bar(x=2)

Вывод:

bar: () {}
foo: x = 5
bar: () {'x': 2}
foo: x = 2

Демо

args и kwargs - это значения, которые являютсяпередается в bar, и в конце те же значения передаются в foo.Если ничего не передано bar, то ничто не передано foo, и используются значения по умолчанию.

super().__init__(*args, **kw) эквивалентно MainApp.__init__(*args, **kw).Значения по умолчанию не наследуются, они просто используются как обычно.

...