1

I was looking in python's grammar and was that you could use the walrus operator in inheritance! Not believing it, I tried it out:

class foo: pass
class bar(foobar := foo): 
    def x(self):
        print("it works!")

b = bar()
b.x()

This does not raise any syntax error (python 3.8.2)! What is the use of it, and how does it work?

Flimzy
  • 60,850
  • 13
  • 104
  • 147
xilpex
  • 2,716
  • 2
  • 10
  • 38
  • 2
    There doesn't have to be a reason. No one needs to specifically decide to allow using two things together based on the existence of a use case. All sorts of things can be combined in non-useful ways. – user2357112 supports Monica Jun 02 '20 at 21:27

3 Answers3

5

It's of no use - so don't use it ;-) Arbitrary expressions are allowed there. For example, this is even more useless:

from random import choice

class C(choice([int, list])):
    pass

Have fun ;-)

Tim Peters
  • 55,793
  • 10
  • 105
  • 118
  • Actually, this is incorrect-- if you take a look at the grammar, it is explicitly there-- it isn't there under the form of an expression. – xilpex Jun 02 '20 at 22:31
  • 2
    @Xilpex: That's an artifact of parser limitations. The parser wouldn't have been able to handle `namedexpr_test` there. It's the same kind of limitation that causes them to have to use `test ':=' test` instead of `NAME ':=' test`. – user2357112 supports Monica Jun 02 '20 at 23:29
1

What is the use of it, and how does it work?

There is no specific use case for the walrus operator in inheritance. It works simply because the class is an expression, so it allows everything an expression allows, including the walrus operator. As pointed out in the comments, you could achieve the same result using:

foobar = foo
class bar(foobar):
    ...

Other things allowed in expressions would work just as well, such as parentheses and function calls:

class bar(((foo))):
    pass

class bar((lambda x: x)(foo)):
    pass
user4815162342
  • 104,573
  • 13
  • 179
  • 246
  • Actually, this is incorrect-- if you take a look at the grammar, it is explicitly there-- it isn't there under the form of an expression. – xilpex Jun 02 '20 at 22:31
  • @Xilpex You're right regarding the grammar. I'm not sure, but it seems like an implementation detail required by some limitation of the parser to produce the _effect_ of arbitrary expressions being allowed. For example, list comprehensions are also listed explicitly. – user4815162342 Jun 02 '20 at 22:50
-1

After a little experimenting (and luck), I found out it is for things like renaming classes while inheriting for them:

class foo:
    def __init__(self, x):
        pass

class bar(foobar := foo):
    def __init__(self):
        foobar.__init__(self, 2)

    def x(self):
        print("it works!")

b = bar()
b.x()

If you remove the walrus operator it does not work (obviously). I'm not sure what use it would really be.

xilpex
  • 2,716
  • 2
  • 10
  • 38
  • Is this different from doing `class bar(foo):` then `foobar = foo` at top-level in the class? – Barmar Jun 02 '20 at 21:23