Devoir utiliser print()
au lieu de print
m’arrache la gueule, je dois l’avouer. J’ai l’impression que ces deux parenthèses ma prennent 5 heures à taper, là où avant mon petit espace était à portée de pouce.
Mais évidement, la décision de faire de print
une fonction est parfaitement rationnelle, et en voici tous les avantages…
print
n’est plus une déclaration, mais une expression
Il y a deux types d’instructions en Python : les déclarations (‘statement’ dans la langue de Chuck Norris) et les expressions.
Les déclarations sont des instructions indépendantes : while
, var = 'valeur'
, try
, def
, etc. On ne peut pas les mettre dans une expression, seulement les imbriquer dans une autre déclaration.
Les expressions, elles, sont imbricables dans n’importe quoi, et elles retournent toujours quelques chose quelque chose, fusse None
. Parmis les expressions on retrouve : les lambdas, les listes en intentions, les appels de fonctions, etc.
Avant, print
était une déclaration, ce qui était très peu souple. Maintenant, c’est un appel de fonction, et donc une expression.
On peut donc utiliser print
dans une autre expression et ainsi :
Dans une lambda :
crier = lambda x, *a, **k: print(x.upper(), *a, **k) |
Dans une liste en intention :
[print(x) for x in range(10)] |
Plus de syntaxe bizarre
Comment supprimer le saut de ligne quand on print avec l’ancienne syntaxe ?
print "Hello", # <- notez la virgule print "You" Hello You |
Avec la nouvelle syntaxe :
print("Hello ", end='') print('You') |
Comment rediriger le print vers stderr avec l’ancienne syntaxe ?
>>> print >> sys.stderr, 'arg !' |
Avec la nouvelle ?
>>> print('arg !', file=sys.stderr) |
Comment faire une liste séparée par des virgules avec l’ancienne syntaxe ?
>>> l = ['Des petits trous', 'des petits trous', 'toujours des petits trous'] >>> print ', '.join(l) Des petits trous, des petits trous, toujours des petits trous |
Avec la nouvelle ?
>>> print(*l, sep=', ') |
En gros, la syntaxe est unifiée, plus besoin de penser à tous ces cas particuliers. Et en plus on peut demander de l’aide avec help(print)
alors qu’avant ça faisait une syntaxe error.
On peut récupérer une référence sur
print
Et donc la passer en paramètre pour faire de l’injection de dépendance :
def truc(a, print=print): # faire un truc avec a print(a); # on peut utiliser print normalement import logging log = loging.getLogger() truc(machin, print=log) # on print pas, on log ! truc(autre_machin, print=lambda *a, **k: None) # ignore les prints ! |
Et également appliquer tous les outils de programmation fonctionnelle de Python :
import sys from functools import partial error = partial(print, file=sys.stderr) error('Wrong !') # va directement sur stderr |
Activer print()
en Python 2.7
Si vous voulez prendre toute de suite de bonnes habitudes, vous pouvez faire, en Python 2.7 :
from __future__ import print_function |
super !!!!!!!!
J’ai “le poinçonneur des lilas” dans la tête maintenant qui s’entre-mêle avec “le requiem pour un con” …
Salut les loulous !
Je crois qu’il manque un « a » dans ce bout de code :
ça devrait pas plutôt être :
?
Correction minime : le __future__, c’est à partir de python 2.6. Je précise pour ceux qui utiliseraient des bousins comme centos.
@Pierre : bien vu.
Une question que j’ai depuis longtemps et peut être idiote. Pour l’injection de dep. quels sont les avantages à print plutôt que sys.stdout et réciproquement ?
Merci.
sys.stdout est un file like object, il expose l’api d’un file like object. C’est basique, c’est essentiellement write(bytes).
print() est une fonction d’affichage, elle expose l’api d’une fonction d’affichage. Elle vient aavec des facilités pour le faire : format, prise en charge d’itérable, etc.
On voudra sys.stdout quand l’idée est d’avoir accès à un fichier de sortie. C’est du bas niveau. Typiquement si on essaye de recoder print (genre une lib de log) ou lorsqu’on travaille avec des fichiers (et qu’on veut donner la possibilité de passer un autre fichier).
On voudra print() dans la plupart des cas où on veut afficher quelque chose, et ne pas se soucier de où ni comment. Print() avec ses *args, end, sep et file permet de configurer la sortie, et est de plus haut niveau, rendant l’opération plus pratique. Print utilise sys.stdout sous le capot.
Many thanks! :)
@Kontre: d’ailleurs, pour ceux qui sont sur du 2.6 en centOS, surtout n’essayez pas de passer en 2.7. J’ai pêté Yum comme ça, et après, c’est foutu. Gardez 2.7 dans un petit virtualenv, tranquilement.
Une idée des perfs de print(*my_list, sep=”,”) VS print(“,”.join(my_list)) ??
Chouette l’injection de dépendance :O
(Subscribing to comments!)
Non, mais je pense qu’à cette échelle de taille de structure de données (moins de 1000 éléments), on s’en cogne. Python va même pas faire semblant de passer du temps dessus.
Tiens je viens de m’apercevoir que le premier paramètre du print est optionnel, et initialisé à une chaîne vide.
Du coup, si on veut juste écrire un saut de ligne, y’a qu’à juste faire print()
Ceci dit, ça marchait déjà avec le print-déclaration. On faisait print tout seul et ça mettait un saut de ligne.
Pour écrire un saut de ligne suivi de 4 fois le mot None, on peut maintenant utiliser la commande
print(print(print(print(print()))))
Et ça, ça n’a pas de prix.
Pour écrire un saut de ligne suivi de 4 fois le mot None, on peut toutefois quand-même utiliser la commande
Et à mon avis, c’est surtout ça qui n’a pas de prix ;P