Outils pour utilisateurs

Outils du site


python

Typage dynamique

Python est un langage à typage dynamique. Il n'est donc pas possible de détecter les erreurs de type ou les fautes frappe avant l'exécution du programmme. Même après avoir exécuté le programme, il n'est pas possible de savoir si le programme est entièrement valide : il y a toujours des branches d'exécution non testées. Pour avoir un semblant de sûreté, il faut donc beaucoup de tests et, surtout, il faut prier.

Pas de récursion terminale

Python fait semblant de gérer la récursion. En pratique, il n'optimise même pas la récursion terminale ; ainsi, le script suivant génère un dépassement de pile :

def foo(n):
  print n
  foo(n+1)
 
foo(0)

Pire, le programme précédant plante après le 998 appels de fonction, sur ma machine. 1000 appels de fonction, ça arrive vite dans la vraie vie. Par conséquent, la récursion — terminale ou non — est fortement déconseillée, à tel point que l'on peut faire comme si Python ne supportait pas la récursion.

Typage fort ?

On entend parfois que Python a un typage fort. Pourtant, comme le C, il ne sait même pas distinguer l'entier du booléen. “True + True” renvoie par exemple 2. Plus précisément, le booléen est considéré comme un sous-type de l'entier, alors que ce sont deux choses conceptuellement très différentes.

If

La condition après le if peut être n'importe quelle valeur. Ce qui est fait est alors très variable. Dans “if x then”, le “then” est exécuté si x vaut une certaine valeur arbitraire (comme 0), ou si x est une liste ne contenant pas d'élément, ou si x est une chaine vide, ou…

Fonctions anonymes

Python est un langage qui fait semblant de gérer les fonctions anonymes. Hélas, cette fonctionnalité est incroyablement limitée. Dans une fonction anonyme, il est interdit de faire une boucle, de déclarer une autre fonction, de modifier une variable, d'utiliser un if ou même d'afficher une valeur. À part additionner ou multiplier les arguments, il n'y a donc pas grand-chose à faire. Ce défaut est flagrant au point que même Guido van Rossum (le concepteur de Python) s'est rendu compte que c'était pourri. À tel point qu'il a voulu supprimer les fonctions anonymes de Python. Il a d'ailleurs reconnu publiquement son incompétence et a avoué ne pas savoir se servir de la fonction fold (appelée parfois reduce).

Instruction / expression

Python est un langage à la syntaxe bancale et décousue, qui fait une différenciation inutile entre une instruction (qui ne renvoie rien) et une expression (qui renvoie une valeur). C'est pour cette raison que Python a besoin du mot-clé return. Sauf –— puisque ça rendrait le langage un minimum consistant —– dans les fonctions anonymes.

Le if de Python est une instruction et ne renvoie donc pas de valeur. Par ailleurs, il a fallu 15 ans à Python pour avoir l'opérateur ternaire, une fonctionnalité que même le C possède. Pour essayer de pallier ce manque, de nombreux développeurs ont recommandé l'astuce suivante :

cond and expr1 or expr2

Bien sûr, c'est très moche. Bien sûr, j'imagine que beaucoup de gens se sont déjà trompés et ont inversé le and et le or. Mais soit, des développeurs conseillent toujours cette astuce (très utile dans les fonctions anonymes où le if est interdit). Il y a même des gens qui l'utilisent pour de vrai et sont contents avec. Jusqu'au jour où la condition est vraie et que expr1 a pour valeur 0 ou ”” : dans ce cas-là, une fois que expr1 a été évalué, c'est expr2 qui est renvoyé. Ceci est un bug extrêmement subtil et perfide : même après avoir testé le script une centaine de fois, ce genre de bug peut subsister. Ainsi, des développeurs plus intelligents ont proposé cette écriture, qui marche dans tous les cas :

(cond and [expr1] or [expr2])[0]

Cela se passe de commentaire. Heureusement, un opérateur ternaire a fini par être ajouté en 2005.

Espaces

La syntaxe de Python prend en compte les espaces pour désambiguïser le code. Ce serait une bonne chose si :

  • c'était optionnel : générer du code Python peut devenir compliqué ;
  • il interdisait le mélange des espaces et tabulations. L'interpréteur considère qu'une tabulation vaut 8 espaces, ce qui n'est pas le cas de tous les éditeurs. C'est une source de nombreux problèmes.

Déclaration automatique de variables

La déclaration d'une variable est automatique et transparente lors d'une assignation. Quand on écrit “a = 42”, il est possible que l'on déclare une nouvelle valeur, ou bien que l'on modifie quelque chose d'existant. Une faute de frappe peut donc passer inaperçue. Et en voulant déclarer une nouvelle valeur, avec un peu de malchance le nom est déjà utilisé plus haut. Bref, beaucoup de sources de bugs.

Pas de switch case

Presque tous les langages proposent une alternative aux suites de if/else pour tester une valeur. Même le C et PHP possèdent un switch case. Mais pas Python.

Python 3

Python était un langage tellement raté que les développeurs ont décidé de casser la compatibilité pour reprendre sur des bases un peu moins bancales. Ça peut se comprendre, mais ça pose d'énormes problèmes :

  • Le convertisseur 2to3 ne marche pas dans tous les cas, vue la nature dynamique de Python.
  • On ne peut pas mélanger Python 2 et Python 3 (contrairement à Perl 6 qui propose un mode de compatibilité)
  • Beaucoup d'entreprises et de projets ne veulent (ou ne peuvent) pas migrer vers Python 3, on se retrouve donc avec un schisme.

Argument par défaut

def foo(a=[]):
    a.append(5)
    return a
 
>>> foo()
[5]
>>> foo()
[5, 5]
>>> foo()
[5, 5, 5]
>>> foo()
[5, 5, 5, 5]
>>> foo()

Autres

  • ”def __init__(self):”, c'est vachement laid quand même.
python.txt · Dernière modification: 2013/05/06 13:23 (modification externe)