1
votes

Syntaxe impaire (opérateur Walrus en héritage)

Je cherchais dans la grammaire de python et j'étais que vous pouviez utiliser l'opérateur morse en héritage! N'y croyant pas, je l'ai essayé:

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

b = bar()
b.x()

Cela ne soulève aucune erreur de syntaxe (python 3.8.2)! À quoi ça sert et comment ça marche?


1 commentaires

Il ne doit pas y avoir de raison. Personne n'a besoin de décider spécifiquement d'autoriser l'utilisation de deux choses ensemble en fonction de l'existence d'un cas d'utilisation. Toutes sortes de choses peuvent être combinées de manière inutile.


3 Réponses :


-1
votes

Après un peu d'expérimentation (et de chance), j'ai découvert que c'était pour des choses comme renommer les classes en héritant pour elles:

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()

Si vous supprimez l'opérateur morse cela ne fonctionne pas (évidemment ). Je ne sais pas à quoi cela servirait vraiment.


1 commentaires

Est-ce différent de faire class bar (foo): puis foobar = foo au plus haut niveau de la classe?



5
votes

Cela ne sert à rien - alors ne l'utilisez pas ;-) Les expressions arbitraires y sont autorisées. Par exemple, c'est encore plus inutile:

from random import choice

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

Amusez-vous bien ;-)


2 commentaires

En fait, c'est incorrect - si vous regardez la grammaire, c'est explicitement là - ce n'est pas là sous la forme d'une expression.


@Xilpex: C'est un artefact des limitations de l'analyseur. L'analyseur n'aurait pas été en mesure de gérer namedexpr_test ici. C'est le même genre de limitation qui les oblige à utiliser test ': =' test au lieu de NAME ': =' test .



1
votes

À quoi ça sert et comment ça marche?

Il n'y a pas de cas d'utilisation spécifique pour l'opérateur morse dans l'héritage. Cela fonctionne simplement parce que la classe est une expression, donc elle autorise tout ce qu'une expression permet, y compris l'opérateur morse. Comme indiqué dans les commentaires, vous pouvez obtenir le même résultat en utilisant:

class bar(((foo))):
    pass

class bar((lambda x: x)(foo)):
    pass

Les autres éléments autorisés dans les expressions fonctionneraient tout aussi bien, comme les parenthèses et les appels de fonction: p>

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

2 commentaires

En fait, c'est incorrect - si vous regardez la grammaire, c'est explicitement là - ce n'est pas là sous la forme d'une expression.


@Xilpex Vous avez raison en ce qui concerne la grammaire. Je ne suis pas sûr, mais cela semble être un détail d'implémentation requis par une limitation de l'analyseur pour produire l ' effet d'expressions arbitraires autorisées. Par exemple, les compréhensions de liste sont également répertoriées explicitement.