Vous le savez peut-être, python 3.10 est sur le point de débarquer en amenant une grande nouveauté pour le langage : du patern matching avec une structure de la forme match case. Comme certains l'ont peut-être remarqué (avec les type hint par exemple) je suis un fanatique de ce genre de gadget syntaxique. J'ouvre ce sujet pour évaluer quelle réputation cette feature a sur Open Classrooms, ou, si c'est trop tôt, ce que vous en attendez, ce que vous craignez, ect... que vous soyez confirmé ou moins expérimenté bien sûr.
Par ailleurs, j'ai remarqué un autre ajout plus anecdotique :
>>> uwu = 42
>>> owu
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'owu' is not defined. Did you mean: 'uwu'?
(Celui-là n'apparaît pas dans le résumé de python insider je crois).
Pour finir, je ne sais pas pourquoi, pythonpool.com proclame que l'ajout de patern matching va permettre la surcharge de fonctions. C'est faux, en tout cas pour l'instant.
Pas le temps de maitriser les changements de la 2.7 qu'on est déjà à la 3.10 ! Un truc que je reprocherais à Python, ça évolue trop vite pour un usage amateur, je n'imagine pas la charge de travail que ça doit être pour un pro qui veut être à jour sur tous les langages de programmation dont il a besoin !!!
Ca permet d'éviter un try except, entre autre, c'est ça ? (Si c'est ça, c'est assez limité)
def func(X): # X = (x, y, z)
# point est un tuple de la forme (x, y)
match point:
case (0, 0):
print("Origine")
case (0, y):
print(f"Y={y}")
case (x, 0):
print(f"X={x}")
case (x, y):
print(f"X={x}, Y={y}")
case _:
raise ValueError("n'est pas un point")
L'équivalent serait ce qui suit n'est-ce pas ?
def func2(X):
try:
x,y = (X[0],X[1])
if (x,y) == (0,0):
print('Origine')
elif not x and y:
print(f'Y={y}')
elif x and not y:
print(f'X={x}')
else:
print(f'X={x}, Y={y}')
except:
raise ValueError("n'est pas un point")
Je me demande ce que ça donnerait si j'avais 25 cas différents du point devue performance. Ça devrait être plus puissant que le switch de C ou C++. Jusqu'ici, je me débrouillais avec les dictionnaires, mais il faut les construire. Ça va me prendre un peu de recul pour évaluer le gain de cette possibilité. J'espère que je pourrai passer plus facilement à la version 3.10 que j'essaie de le faire pour passer de 3.9.6 à 3.9.7 ... Il me semble que les ajouts sont "relativement" bien documentés dans la page de download du site officiel de Python.
Le Tout est souvent plus grand que la somme de ses parties.
@ErispoeLeNarvalo pas exactement, tes deux fonctions ne donneraient pas la même chose pour X="ab" ou X=(1,2,3) par ex (je ne compte pas l'erreur du match point au lieu de match X )
match case (0, y):
ça vérifie le type et la longueur, il n'y a pas de besoin de try, c'est équivalent à:
if isinstance(point, (list, tuple)) and len(point) == 2 and not point[0]:
Voici un équivalent pour le total :
def func(X):
if isinstance(X, (list, tuple)) and len(X) == 2:
x, y = X
if (x, y) == (0, 0):
print("Origine")
elif not x:
print(f"Y={y}")
elif not y:
print(f"X={x}")
else:
print(f"X={x}, Y={y}")
else:
raise ValueError("n'est pas un point")
Toujours une ligne de gagnée, mais c'est un truc assez puissant ya de meilleurs exemples dans la PEP 622
- Edité par thelinekioubeur 28 septembre 2021 à 9:29:09
@thelinekioubeur Pas vraiment non plus len(X) peut être supérieur ou égale à 2, non ?
def func(X): # X = (x, y, z)
X="ab" ou X=(1,2,3)
Ma func2 attend une liste ou un tuple comme la fonction avec le match/case, pas besoin de couvrir l'intégralité des possibilités. Sinon ça soulève une exception, nan ?
Edit : isinstance je l'utilise jamais, non plus , mais plutôt :
Python 3.10 était censé être disponible aujourd'hui. Ça ne semble pas êttre le cas. Est-ce une bonne idée que d'installer une nouvelle version le jour de son lancement officiel? Je l'ai fait avec Python 3.9.6 et je n'ai pas eu de problème. J'ai bien hâte de voir ce que donne le match case
Le Tout est souvent plus grand que la somme de ses parties.
Je suis en retard sur vous, semble-t-il J'ai tout de même trouvé le truc pour l'équivalent du default de C ou C++ - a = input(">") match a: case '1': print("cas un") case '2': print("cas deux") case _: print("autre") - Autre truc intéressant (pour moi). Le paramètre "strict" de zip qui donne une erreur si les listes ne sont pas de même longueur.
Comment faire des comparaisons de performances?
Pour simuler un switch, j'utilise un dictionnaire.
Ou bien devrais-je comparer à des if elif ... else en cascade?
Le dictionnaire sera nettement plus rapide et le if elif sera plus lent?
edit: Voici un petit générateur de code pour comparer le match case avec les if elif. J'en ai fait autant pour le dictionnaire. Je vous laisse le tester, mais je peux dire que c'est désastreux pour le match case L'intérêt sera dans la clarté et la flexibilité. - file=open("am.py", "w") n=1000 file.write("from time import perf_counter\n") file.write(f"n={n}\n") file.write("begin=perf_counter()\n") file.write("for _ in range(1, n+1):\n") file.write(" "*4+"for i in range(1, n+1):\n") file.write(" "*8+"match i:\n") for i in range(1, n+1): file.write(" "*12+f"case {i}: b=i\n") file.write("print(round(perf_counter()-begin, 3), 'secondes')\n") file.write("begin=perf_counter()\n") file.write("for _ in range(1, n+1):\n") file.write(" "*4+"if i==1: b=i\n") for i in range(2, n+1): file.write(" "*4+f"elif i=={i}: b=i\n") file.write("print(round(perf_counter()-begin, 3), 'secondes')\n")
- Edité par PierrotLeFou 5 octobre 2021 à 8:00:16
Le Tout est souvent plus grand que la somme de ses parties.
Le match case n'est pas fait pour faire ça Puis là il te manque une boucle pour tes elifs, c'est le match case qui est plus rapide !
Pour comparer les perfs, je dirais qu'il vaut mieux le faire avec un match case de quelques lignes, en le relançant n fois avec timeit.timeit.
Mais note que:
- Pour les use cases la différence de perfs sera négligeable
- L'intérêt du match case ce sont les use cases où sa syntaxe permet de simplifier par rapport aux elifs (voir les exemple de la PEP 622 encore une fois)
Sinon, 3.10 est sorti
- Edité par thelinekioubeur 5 octobre 2021 à 8:20:10
Mea culpa ... j'avais une double boucle pour tester le dictionnaire et je l'ai éliminé. J'ai bien trouvé python 3.10 ... Je suis sur Windows et j'utilise perf_counter pour mes évaluations de performances, c'est correct? En effet, match case est plus rapide que if elif
Le Tout est souvent plus grand que la somme de ses parties.
Avec le dictionnaire, ce code devrait être correct: Le désavantage du dictionnaire est qu'on ne peut pas exécuter n'importe quoi facilement. J'ai déjà mis des fonctions comme valeurs, mais le nombre de paramètres était le même pour toutes. - dico=dict() for i in range(1, n+1): dico[i]=i begin=perf_counter() for _ in range(1, n+1): for i in range(1, n+1): b=dico[i] print(round(perf_counter()-begin, 3), 'secondes') - 10.222 secondes 0.088 secondes
edit:
J'ai oublié de dire que le premier temps est toujours celui des martch case
- Edité par PierrotLeFou 5 octobre 2021 à 18:21:53
Le Tout est souvent plus grand que la somme de ses parties.
Les nouveautés de Python 3.10.0rc2
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
typage structurel ftw
Le Tout est souvent plus grand que la somme de ses parties.
Le Tout est souvent plus grand que la somme de ses parties.
Le Tout est souvent plus grand que la somme de ses parties.
Le Tout est souvent plus grand que la somme de ses parties.
Le Tout est souvent plus grand que la somme de ses parties.