Python Forum
[Python Core] Keyword for direct passthrough of **kwargs to super().__init__
Thread Rating:
  • 1 Vote(s) - 3 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Python Core] Keyword for direct passthrough of **kwargs to super().__init__
#1
First of all: I just started programming in Python a couple of months ago, so please be patient if I ask a stupid question. I started this question on Stackoverflow but it might be more appropriated here...


Could there be a "magical keyword" (which obviously only works if no **kwargs is specified) so that the
__init__(*args, some_keyword=None, ***pass_through_kwargs)
so that all unexpected kwargs (everything that would be in kwargs if they were specified instead) are directly passed through to the super().__init__? In an unmodifiable way in the background and without the users active part of putting them in the super().__init__ themselves. This would make the readability much easier and they could be safely ignored by autocomplete and automated documentation for this class.

In the following diagram Mouse is ever only instantiated with let's say a name. Just to make the super-calls (in red) down the line work I have to add **kwargs (to specify the number_of_holes the cheese has) and hand them over by hand. Can't I just tell Mouse and Animal "Whatever you don't know: just pass it directly down to super()"?
[Image: gBnXO.png]

I want something like this to work:
class Animal:
    def __init__(self, species, ***pass_through_kwargs):
        self.species = species
        super().__init__()
class Mouse(Animal):
    def __init__(self, name, ***pass_through_kwargs):
        self.name = name
        super().__init(species="Mouse")
class Cheese:
    def __init__(self, num_of_holes=0):
        self.num_of_holes = num_of_holes
class MickeyMouse(Mouse, Animal):
    def __init__(self):
        super().__init__(name='Mickey Mouse', num_of_holes=2)
Reply
#2
well, *args is catch all for positional arguments, **kwargs - for keyword (named) argument, so there is no way to have one more catch-all-pass-trough. You would do something like
class Animal:
    def __init__(self, **kwargs):
        self.species = kwargs.get('species', None)
class Mouse(Animal):
    def __init__(self, **kwargs):
        self.name = kwargs.get('name', None)
        super().__init__(**kwargs)

mouse = Mouse(species="Mouse", name='Mikey Mouse')
print(mouse.species)
print(mouse.name)
or if you want to have some explicit mentioned arguments
class Animal:
    def __init__(self, species, **kwargs):
        self.species = species
class Mouse(Animal):
    def __init__(self, name, **kwargs):
        self.name = name
        super().__init__(**kwargs)

mouse = Mouse(species="Mouse", name='Mikey Mouse')
print(mouse.species)
print(mouse.name)
in both cases output is
Mouse
Mikey Mouse

the second example assume the parent class has no argument name
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#3
(May-25-2018, 05:17 PM)buran Wrote: well, *args is catch all for positional arguments, **kwargs - for keyword (named) argument, so there is no way to have one more catch-all-pass-trough.

I know that it is not possible with the current version of python. What I was asking is, if it would be possible to implement something like this for future versions of Python.
I want the autocomplete and all the automatically generated docstrings to be as easy to understand as possible. I want something that signals a docstring generator "Hey, this class can in principle take **kwargs as an input, but it just passes them to their super class without doing anything to them. So for this class: just ignore them".

If a user types Animal( I want the IDE to show just Animal(species) and not some obscure Animal(species, **kwargs) because when you create an instance of this class yourself you never need to input any kwargs as they would throw an error if you did so anyways.
Reply
#4
(May-25-2018, 05:30 PM)miallo Wrote: I know that it is not possible with the current version of python. What I was asking is, if it would be possible to implement something like this for future versions of Python.
sorry, this was not clear from your original question. At least I didn't understood your question as such - that's why I moved it to General Coding Help. If it is regarding [desired] future functionality - than indeed News and Discussions is more appropriate. I will return it there now.
(May-25-2018, 05:30 PM)miallo Wrote: If a user types Animal( I want the IDE to show just Animal(species) and not some obscure Animal(species, **kwargs) because when you create an instance of this class yourself you never need to input any kwargs as they would throw an error if you did so anyways.
you are free to have all keywords you want explicitly mentioned, and then have **kwargs as catch all for all that are irrelevant and simply ignore them... (that is my second example)
And it will throw error because it's not a keyword argument, but dict of keyword arguments.
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#5
(May-25-2018, 05:38 PM)buran Wrote: you are free to have all keywords you want explicitly mentioned, and then have **kwargs as catch all for all that are irrelevant and simply ignore them... (that is my second example)
I know that it is possible to 'do it by hand' but when your IDE shows you the arguments a class takes you will think for a second if you need to look into the documentation of this class what kwargs you can pass in. I personally find this kind of ugly (even if you have a good documentation - should it just say "Yes, the init says you can pass in kwargs but doing so will crash this program"?).
Reply
#6
(May-25-2018, 05:52 PM)miallo Wrote: I know that it is possible to 'do it by hand' but when your IDE shows you the arguments a class takes you will think for a second if you need to look into the documentation of this class what kwargs you can pass in. I personally find this kind of ugly (even if you have a good documentation - should it just say "Yes, the init says you can pass in kwargs but doing so will crash this program"?).
sorry, I don't get what you want. Even in your original example you have them explicitly defined, in addition to this "new" catch-all-pass-trough thing
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#7
Since it would probably be quite bad to just turn this feature on by default for all classes I thought I would invent a keyword that (if present in the init) would do it. If not: do it the 'old' way. What you might see from my example code is that the super().__init__ calls don't have the ***pass_through_kwargs specified.
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020