[Python-ideas] Keyword for direct pass through of kwargs to super
Michael Lohmann
mial.lohmann at gmail.com
Sun May 27 13:19:56 EDT 2018
I realized that bypassing kwargs is probably the least important thing of this idea - so if implemented it definitely had to get a better name. Just look at the following example:
class Magic:
magic_number = 42
def __init__(self):
A.magic_number = 0 # As soon as you look too deep into it all the Magic vanishes
class Foo(Magic):
def __init__(self):
print("foo")
# Let's say we want magic_number==42 in Foo
# So you can’t call super().__init__ here if it is not in the middle of an MRO
# Technically you could get it working by going to the first init in the MRO of self after Foo \
# that isn’t in the MRO of Foo but you can see that this gets quite ugly to write (and read!).
# And then you would still have the problem of indicating that Foo seems to accepted kwargs as input
class Bar:
def __init__(self, bar):
print("bar:", bar)
class FooBar(Foo, Bar):
def __init__(self):
# There is no easy way right now to avoid writing
Foo.__init__()
Bar.__init__(bar="bar“)
But if Foo adopted this protocol of "automated MRO handling"/"cooperativity" (or however you want to call it) Bar.__init__ could be called automatically. What do I mean by that? Well, basically do automatically what I described in the comment of Foo if no super().__init__ call was registered in any cooperative class.
Okay, this example might be a bit far-fetched, but it shows, that you could easily get the MRO working as expected with a simple super().__init__(bar="bar") in FooBar.
> This shouldn't be a problem if each method along the way
> absorbs all the arguments it knows about, and only passes
> on the ones it doesn’t.
Two remarks: 1) Everything my idea has to offer really is just reasonable if you don’t have single inheritance only and 2) This wasn’t really my problem with the current status (in fact: the way I would tackle this problem would also only work if all kwargs get fully consumed). But:
What bugs me is that in my example from yesterday (
class Aardvark:
def __init__(self, quantity, **kwargs):
print("There is some quantity:", quantity)
# I actually don’t care about **kwargs and just hand them on
super().__init__(**kwargs)
class Clever:
def __init__(self, cleverness=1):
print("You are %d clever“ % cleverness)
class Ethel(Aardvark, Clever):
"""Ethel is a very clever Aardvark"""
def __init__(self):
super().__init__(quantity="some spam", cleverness=1000)
) if you want to instantiate an Aardvark directly there is NO WAY EVER that you could give him any kwargs. So why should the __init__ indicate something else? Well, just to make the MRO work. All I want is to make it as obvious as possible that an Aardvark ONLY takes `quantity` as input, but is fully "cooperative" with other classes if it is in the middle of the MRO (by which I mean that it will automatically call the __init__ and hand on any kwargs it didn’t expect to a class from a different branch of the class hierarchy).
More information about the Python-ideas
mailing list