Reputation: 109
I have some trouble grasping this, I guess pretty simple, concept. I am creating some tkinter app (not relevant), and I´m playing with inheriting attributes through super and *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'}
I mean I kind of understand what is going on, Im not blind, but still wonder, why master, y and x are not inherited as kwargs immediatly, after all, they are keyword arguments in MainApp init method. I would assume super() method will take care of that. Application works fine but I am kind of frustrated from not understanding this and would appreciate some insight.
How is x and y attribute inherited when..
def __init__(self, *args, **kwargs)
super().__init__(*args, **kwargs)
.. does not specify x or y. And even when runnin this:
def __init__(self, master):
super().__init__(master)
It runs fine and inherits x and y attributes..
Once again, I would appreciate some insight, thank you.
Upvotes: 1
Views: 216
Reputation: 36033
This has nothing to do with super
or inheritance. It's just parameters taking on their default values when no arguments are passed. Here's a simple example:
def foo(x=5):
print('foo: x =', x)
def bar(*args, **kwargs):
print('bar:', args, kwargs)
foo(**kwargs)
bar()
bar(x=2)
Output:
bar: () {}
foo: x = 5
bar: () {'x': 2}
foo: x = 2
args
and kwargs
are the values that are passed to bar
, and in the end the same values are passed to foo
. If nothing gets passed to bar
, then nothing is passed to foo
, and the default values are used.
super().__init__(*args, **kw)
is equivalent to MainApp.__init__(*args, **kw)
. The default values aren't being 'inherited', they're just being used as normal.
Upvotes: 1