Í‚« Factoriser Í‚» un param̓¨tre

Le
Olivier Miakinen
Bonjour,

Dans une classe j'ai la méthode suivante. Peu importe le détail de ce
qu'elle fait, le point important est tous ces « print » avec le paramètre
« file=file ».

def print(self, indent=0, *, file=sys.stdout):
"""Imprime un filtre auto-indenté"""
print(" "*indent, end="", file=file)
if self.neg: print("!", end="", file=file)
if (self.t == "RE"):
print(f"{self.key} /{self.regex.pattern}/", file=file)
else:
print(self.t, file=file)
for subf in self.subs: subf.print(indent+1, file=file)

Ma question : y a-t-il un moyen de « factoriser » ce paramètre, avec une
syntaxe du style « with file=file », de façon Í  pouvoir le supprimer de
tous les appels Í  la fonction print() ?

[
Question subsidiaire : comment traduire au mieux le sens de « print » dans
le commentaire au début de ma fonction ? Je n'ai pas l'impression que le
terme « imprime » ni le terme « affiche » ne conviennent dans tous les cas.
]

--
Olivier Miakinen
  • Partager ce contenu :
Vos réponses
Trier par : date / pertinence
Benoit Izac
Le #26571704
Bonjour,
Le 11/04/2021 Í  15:26, Olivier Miakinen a écrit dans le message
Dans une classe j'ai la méthode suivante. Peu importe le détail de ce
qu'elle fait, le point important est tous ces « print » avec le paramètre
« file=file ».
def print(self, indent=0, *, file=sys.stdout):
"""Imprime un filtre auto-indenté"""
print(" "*indent, end="", file=file)
if self.neg: print("!", end="", file=file)
if (self.t == "RE"):
print(f"{self.key} /{self.regex.pattern}/", file=file)
else:
print(self.t, file=file)
for subf in self.subs: subf.print(indent+1, file=file)
Ma question : y a-t-il un moyen de « factoriser » ce paramètre, avec une
syntaxe du style « with file=file », de façon Í  pouvoir le supprimer de
tous les appels Í  la fonction print() ?

Je vois deux possibilités :
1. tu utilises file pour écrire :
def print(self, indent=0, *, file=sys.stdout):
"""Imprime un filtre auto-indenté"""
file.write(" "*indent)
if self.neg: file.write("!")
if (self.t == "RE"):
file.write(f"{self.key} /{self.regex.pattern}/n")
else:
file.write(f'{self.t}n')
for subf in self.subs: subf.print(indent+1, file=file)
2. tu remplaces le print() par le tiens :
def print(self, indent=0, *, file=sys.stdout):
"""Imprime un filtre auto-indenté"""
def print(*args, **kw):
kw['file'] = file
__builtins__.print(*args, **kw)
print(" "*indent, end="")
if self.neg: print("!", end="")
if (self.t == "RE"):
print(f"{self.key} /{self.regex.pattern}/")
else:
print(self.t, file=file)
for subf in self.subs: subf.print(indent+1)
[
Question subsidiaire : comment traduire au mieux le sens de « print » dans
le commentaire au début de ma fonction ? Je n'ai pas l'impression que le
terme « imprime » ni le terme « affiche » ne conviennent dans tous les cas.
]

Écrire la représentation du filtre dans «Â file »Â ?
Après vu que je ne sais pas trop ce que ça représente, c'est difficile
de dire.
--
Benoit Izac
Alain Ketterlin
Le #26571707
Olivier Miakinen
Dans une classe j'ai la méthode suivante. Peu importe le détail de ce
qu'elle fait, le point important est tous ces « print » avec le paramètre
« file=file ».
def print(self, indent=0, *, file=sys.stdout):
"""Imprime un filtre auto-indenté"""
print(" "*indent, end="", file=file)
if self.neg: print("!", end="", file=file)
if (self.t == "RE"):
print(f"{self.key} /{self.regex.pattern}/", file=file)
else:
print(self.t, file=file)
for subf in self.subs: subf.print(indent+1, file=file)
Ma question : y a-t-il un moyen de « factoriser » ce paramètre, avec une
syntaxe du style « with file=file », de façon Í  pouvoir le supprimer de
tous les appels Í  la fonction print() ?

Il n'y a pas vraiment de solution pour cela, sauf Í  définir une fonction
locale :
def print(self, indent=0, *, file=sys.stdout):
def pr (*p, **k): print (*p, **k, file=file)
...
et utiliser pr (...) dans la suite (j'ai pas essayé, hein, cela dépend
peut-être de la version de python pour l'ajout de "file=file" après **k).
Une autre solution est de rediriger sys.stdout, ce qui est peut-être le
plus simple si c'est applicable. Voir
https://docs.python.org/3/library/contextlib.html#contextlib.redirect_stdout
[
Question subsidiaire : comment traduire au mieux le sens de « print » dans
le commentaire au début de ma fonction ? Je n'ai pas l'impression que le
terme « imprime » ni le terme « affiche » ne conviennent dans tous les cas.
]

J'utilise "afficher" en général, parce qu'imprimer m'évoque
immanquablement le papier...
-- Alain.
Olivier Miakinen
Le #26571710
Le 11/04/2021 19:27, Benoit Izac m'a répondu :
Ma question : y a-t-il un moyen de « factoriser » ce paramètre, avec une
syntaxe du style « with file=file », de façon Í  pouvoir le supprimer de
tous les appels Í  la fonction print() ?

Je vois deux possibilités :
1. tu utilises file pour écrire :
def print(self, indent=0, *, file=sys.stdout):
"""Imprime un filtre auto-indenté"""
file.write(" "*indent)
if self.neg: file.write("!")
if (self.t == "RE"):
file.write(f"{self.key} /{self.regex.pattern}/n")
else:
file.write(f'{self.t}n')
for subf in self.subs: subf.print(indent+1, file=file)

Intéressant. On perd la souplesse du print avec les arguments multiples,
mais dans mon cas ça n'est pas un problème. De même pour la perte de
l'argument end, qui m'arrange plutÍ´t bien en l'occurrence (pas de 'n'
par défaut).
2. tu remplaces le print() par le tiens :
def print(self, indent=0, *, file=sys.stdout):
"""Imprime un filtre auto-indenté"""
def print(*args, **kw):
kw['file'] = file
__builtins__.print(*args, **kw)
print(" "*indent, end="")
if self.neg: print("!", end="")
if (self.t == "RE"):
print(f"{self.key} /{self.regex.pattern}/")
else:
print(self.t, file=file)
for subf in self.subs: subf.print(indent+1)

Oh, une fonction dans une méthode, avec le même nom qui plus est !
Je sens que je suis loin d'appréhender toute la puissance de ce langage
de programmation...
[
Question subsidiaire : comment traduire au mieux le sens de « print » dans
le commentaire au début de ma fonction ? Je n'ai pas l'impression que le
terme « imprime » ni le terme « affiche » ne conviennent dans tous les cas.
]

Écrire la représentation du filtre dans «Â file »Â ?
Après vu que je ne sais pas trop ce que ça représente, c'est difficile
de dire.

C'est vrai que je n'ai pas voulu entrer dans les détails. En gros ça affiche le
contenu d'un filtre sous forme lisible pour l'utilisateur, par exemple :
OR
AND
from: subject: Un petit test
AND
reply-to: organization: inexistante
et par défaut cette sortie est juste envoyée sur stdout (donc affichée), mais il
se pourrait que j'aie parfois besoin de l'envoyer dans un fichier.
Oui, « écrire » ce n'est pas mal.
Merci pour tout !
--
Olivier Miakinen
Olivier Miakinen
Le #26571711
Le 11/04/2021 19:59, Alain Ketterlin m'a répondu :
Ma question : y a-t-il un moyen de « factoriser » ce paramètre, avec une
syntaxe du style « with file=file », de façon Í  pouvoir le supprimer de
tous les appels Í  la fonction print() ?

Il n'y a pas vraiment de solution pour cela, sauf Í  définir une fonction
locale :
def print(self, indent=0, *, file=sys.stdout):
def pr (*p, **k): print (*p, **k, file=file)
...
et utiliser pr (...) dans la suite (j'ai pas essayé, hein, cela dépend
peut-être de la version de python pour l'ajout de "file=file" après **k).

Je ne connaissais pas la possibilité des fonctions locales avant de lire la
réponse de BenoÍ®t. Si ta méthode condensée ne fonctionne pas, il y aura
toujours la sienne, avec « k['file'] = file » (ça ne fait jamais qu'une
instruction de plus).
Une autre solution est de rediriger sys.stdout, ce qui est peut-être le
plus simple si c'est applicable. Voir
https://docs.python.org/3/library/contextlib.html#contextlib.redirect_stdout

Ah, ça je ne connaissais pas non plus. J'ai eu peur en lisant le titre que
la redirection dure jusqu'Í  la fin du programme, mais visiblement ce n'est
pas le cas (« temporarily redirecting »). Ça me plait bien aussi.
Et oui, il me semble bien que dans mon cas ce soit applicable.
[
Question subsidiaire : comment traduire au mieux le sens de « print » dans
le commentaire au début de ma fonction ? Je n'ai pas l'impression que le
terme « imprime » ni le terme « affiche » ne conviennent dans tous les cas.
]

J'utilise "afficher" en général, parce qu'imprimer m'évoque
immanquablement le papier...

Oui, imprimer ne me satisfait pas pour la même raison.
Mais si on redirige vers un fichier, ce n'est plus vraiment afficher... Bon,
cela dit il s'agit juste d'un commentaire, ce n'est pas primordial non plus.
Cordialement,
--
Olivier Miakinen
Olivier Miakinen
Le #26571714
Le 11/04/2021 21:40, Benoit Izac m'a répondu :
[...]
et par défaut cette sortie est juste envoyée sur stdout (donc
affichée), mais il se pourrait que j'aie parfois besoin de l'envoyer
dans un fichier.
Oui, « écrire » ce n'est pas mal.

«Â Envoyer » sinon puisque tu l'utilises ci-dessus pour décrire ce que tu
fais.
"""Envoie le contenu du filtre sur/dans file"""

Certes. ;-)
(et merci de me l'avoir fait trouver inconsciemment)
--
Olivier Miakinen
Poster une réponse
Anonyme