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?
3 Réponses :
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.
Est-ce différent de faire class bar (foo):
puis foobar = foo
au plus haut niveau de la classe?
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 ;-)
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
.
À 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)): passLes 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): ...
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.
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.