The difference in behavior between super () .__ init __ () and explicit superclass __init __ () in Python

I get an unexplained difference in behavior between using super().__init__() and explicitly calling the superclass constructor in my code.

 class IPElement(object): def __init__(self, ip_type='IPv4'): self.ip_type = ip_type class IPAddressSimple(IPElement): def __init__(self, ip_name, ip_type='IPv4'): self.ip_name = ip_name super().__init__(self, ip_type=ip_type) 

Here the line super().__init__(self, ip_type=ip_type) leads to an error like:

 TypeError: __init__() got multiple values for argument 'ip_type' 

When I change the call to transmit ip_type by position (for example, super().__init__(self, ip_type) , I get a different type of error:

 TypeError: __init__() takes from 1 to 2 positional arguments but 3 were given 

None of these errors make sense to me, and when I replace super() with the explicit name of the superclass, everything works as expected. The following works just fine, as does passing ip_type by position:

 class IPAddressSimple(IPElement): def __init__(self, ip_name, ip_type='IPv4'): self.ip_name = ip_name IPElement.__init__(self, ip_type=ip_type) 

I can, of course, use an explicit call to the __init__ superclass method if necessary, but I would like to understand why super() does not work here.

+6
source share
1 answer

super() already passes self for you. super(IPAddressSimple) does not know about self , so in this case you will need to call super(IPAddressSimple).__init__(self, ip_type) . But super() (which is the syntactic sugar for super(IPAddressSimple, self) ) knows self and processes it, so you should only ip_type manually.

+3
source

Source: https://habr.com/ru/post/979916/


All Articles