Quelle est une façon propre de créer un with
multi-lignes en python? Je veux ouvrir plusieurs fichiers dans un seul with
, mais c'est assez loin à droite que je le veux sur plusieurs lignes. Comme ça:
class Dummy:
def __enter__(self): pass
def __exit__(self, type, value, traceback): pass
with Dummy() as a, Dummy() as b,
Dummy() as c:
pass
Malheureusement, c'est un SyntaxError
. J'ai donc essayé ceci:
with (Dummy() as a, Dummy() as b,
Dummy() as c):
pass
Également une erreur de syntaxe. Cependant, cela a fonctionné:
with Dummy() as a, Dummy() as b,\
Dummy() as c:
pass
Et si je voulais placer un commentaire? Cela ne fonctionne pas:
with Dummy() as a, Dummy() as b,\
# my comment explaining why I wanted Dummy() as c\
Dummy() as c:
pass
Il n'y a pas non plus de variation évidente sur l'emplacement du \
s.
Existe-t-il un moyen propre de créer une instruction with
sur plusieurs lignes qui autorise les commentaires à l'intérieur?
Étant donné que vous avez balisé ceci Python 3, si vous devez intercaler des commentaires avec vos gestionnaires de contexte, j'utiliserais un contextlib.ExitStack
:
with ExitStack() as stack:
a = stack.enter_context(Dummy()) # Relevant comment
b = stack.enter_context(Dummy()) # Comment about b
c = stack.enter_context(Dummy()) # Further information
Cela équivaut à
with Dummy() as a, Dummy() as b, Dummy() as c:
Cela a l'avantage que vous pouvez générer vos gestionnaires de contexte dans une boucle au lieu de devoir répertorier chacun séparément. La documentation donne l'exemple que si vous voulez ouvrir un tas de fichiers et que vous avez les noms de fichiers dans une liste, vous pouvez le faire
with ExitStack() as stack:
files = [stack.enter_context(open(fname)) for fname in filenames]
Si vos gestionnaires de contexte prennent tellement d'espace à l'écran que vous souhaitez mettre des commentaires entre eux, vous en avez probablement assez pour vouloir utiliser une sorte de boucle.
Comme le mentionne M. Deathless dans les commentaires, il y a un contextlib backport sur PyPI sous le nom contextlib2
. Si vous êtes sur Python 2, vous pouvez utiliser l'implémentation du backport de ExitStack
.
Cela me semble le plus simple:
with open('firstfile', 'r') as (f1 # first
), open('secondfile', 'r') as (f2 # second
):
pass
Ce n'est pas exactement propre, mais vous pouvez le faire:
with Dummy() as a, Dummy() as b, (
#my comment
Dummy()) as c:
pass
Il n'y a pas d'erreurs de syntaxe, mais ce n'est pas le plus propre. Vous pouvez également faire ceci:
with Dummy() as a, Dummy() as b, Dummy(
#my comment
) as c:
pass
Pensez à trouver un moyen de le faire sans utiliser les commentaires au milieu du with
.
Je garderais les choses simples et lisibles en ajoutant le commentaire avant l'instruction with
, ou sur la ligne elle-même:
# my comment explaining why I wanted Dummy() as c
with Dummy() as a, Dummy() as b,\
Dummy() as c: # or add the comment here
pass
Comme réponse de TigerhawkT , mais avec un retrait qui ne déclenche pas erreur E124 de pycodestyle :
with (
open('firstfile', 'r')) as f1, ( # first
open('secondfile', 'r')) as f2: # second
pass
OMI c'est toujours moche, mais au moins ça passe le linter.