Question

    

Cette question a déjà une réponse ici:

         

Supposons que vous avez trois objets que vous acquérez via le gestionnaire de contexte, par exemple verrouillage A, une connexion db et un socket IP. Vous pouvez les acquérir par:

with lock:
   with db_con:
       with socket:
            #do stuff

Mais est-il un moyen de le faire dans un bloc? quelque chose comme

with lock,db_con,socket:
   #do stuff

En outre, il est possible, étant donné un tableau de longueur inconnue des objets qui ont des gestionnaires de contexte, est-il possible de faire en quelque sorte:

a=[lock1, lock2, lock3, db_con1, socket, db_con2]
with a as res:
    #now all objects in array are acquired

Si la réponse est, est-il « non » parce que la nécessité d'une fonction d'une telle implique une mauvaise conception, ou peut-être je devrais suggérer dans un pep? :-P

Était-ce utile?

La solution

Python 2.7 et 3.1 et au-dessus , vous pouvez écrire:

with A() as X, B() as Y, C() as Z:
    do_something()

Ceci est normalement la meilleure méthode à utiliser, mais si vous avez une liste de longueur inconnue des gestionnaires de contexte vous aurez besoin l'une des méthodes ci-dessous.


Python 3.3 , vous pouvez entrer une liste de longueur inconnue des gestionnaires de contexte à l'aide contextlib.ExitStack :

with ExitStack() as stack:
    for mgr in ctx_managers:
        stack.enter_context(mgr)
    # ...

Cela vous permet de créer les gestionnaires de contexte que vous les ajoutez à la ExitStack, ce qui empêche le problème possible avec contextlib.nested (mentionné ci-dessous).

contextlib2 fournit un rétroportage ExitStack pour Python 2.6 et 2.7.


Python 2.6 et au-dessous , vous pouvez utiliser

Autres conseils

La première partie de votre question est possible dans Python 3.1 .

  

Avec plus d'un élément, sont traités comme si multiples avec des déclarations ont été imbriquées les gestionnaires de contexte:

with A() as a, B() as b:
    suite
     

est équivalent à

with A() as a:
    with B() as b:
        suite
     

Changement dans la version 3.1 : Prise en charge de multiples expressions de contexte

Réponse de

@ interjay est correcte. Toutefois, si vous devez le faire pour les gestionnaires de contexte à long, par exemple les gestionnaires de contexte de mock.patch, alors vous rendrez vite compte que vous voulez briser ce à travers les lignes. Il se trouve que vous ne pouvez pas les envelopper dans parens, de sorte que vous devez utiliser des barres obliques inverses. Voici ce qui ressemble à:

with mock.patch('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa') as a, \
        mock.patch('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb') as b, \
        mock.patch('cccccccccccccccccccccccccccccccccccccccccc') as c:
    do_something()

La deuxième partie de votre question est résolue avec contextlib.ExitStack Python 3.3 .

À la suite de @ réponse de sage88 vous pouvez toujours attribuer ces patchs ont des noms de variables significatives avant d'entrer en eux.

Vous pouvez créer ces patches dans plusieurs lignes

a_patch = mock.patch('aaaaaaa') 
b_patch = mock.patch('bbbbbbb')
c_patch = mock.patch('ccccccc') 
with a_patch as a, b_patch as b, as c:    
    do_something()
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top