super() in Python 3

אורי uri at speedy.net
Tue Jul 16 11:43:20 EDT 2019


Hi,

Thanks for your explanation. But I tried your code and it doesn't work
(with Django==1.11.22):

  File "<...>\site-packages\django\test\runner.py", line 600, in run_tests
    suite = self.build_suite(test_labels, extra_tests)
  File "<...>\speedy\core\base\test\models.py", line 35, in build_suite
    return super().build_suite(test_labels=test_labels, *args, **kwargs)
TypeError: build_suite() got multiple values for argument 'test_labels'


אורי
uri at speedy.net


On Tue, Jul 16, 2019 at 3:13 PM Rhodri James <rhodri at kynesim.co.uk> wrote:

> Hi there!  A lot of the answers to your questions are at least implied
> in the Fine Manual
> (https://docs.python.org/3/library/functions.html#super), but it's not
> very clear and written more for precision than comprehension.  Here's my
> attempt at explaining :-)
>
> On 16/07/2019 11:08, אורי wrote:
> > Hi,
> >
> > 1. When we use super() in Python 3, we don't pass it the first argument
> > (self). Why?
>
> Actually the first argument to super() isn't self, it's the class that
> we want the superclass of.  The *second* argument is self.  In the
> normal course of using super() inside a class method, these arguments
> will almost always be the class itself and the instance the method was
> called on.  Since that's almost always the case, the compiler offers us
> a short-cut: omit the "cls" and "self" and the compiler will fill them
> in for us.  That way we don't have to repeat ourselves and risk
> mis-typing something.
>
> > What happens if the first argument is not self?
>
> The first argument of what?  I'm not sure what you're getting at here.
>
> > I think it would make more sense to use something like
> > self.super().__init__(*args, **kwargs) or something like this.
>
> That would mean either forbidding classes to have a method named "super"
> or accepting that users' classes could completely screw up inheritance
> for their subclasses.
>
> > 2. I want to override a function called build_suite in an inherited
> class.
> > The function receives an argument "test_labels" which I want to change (I
> > define it if it's not defined), but I don't do anything with the argument
> > "extra_tests". Is it possible to include "extra_tests" in *args, **kwargs
>
> Yes.
>
> > and how?
>
> Don't list it in your parameters :-)
>
> def build_suite(self, test_labels=None, *args, **kwargs):
>      ...
>      return super().build_suite(test_labels=test_labels, *args, **kwargs)
>
> > I think maybe they will release another version in the future
> > without "extra_tests", or with additional arguments, and I don't want to
> > have to change my code then.
>
> With a shim layer like this, your chances of getting away with making no
> changes to your code when an API you use changes are rather small.
>
> --
> Rhodri James *-* Kynesim Ltd
> --
> https://mail.python.org/mailman/listinfo/python-list
>



More information about the Python-list mailing list