这个问题已经有一个答案在这里:

假设有三个对象你获得通过方面的经理,例如锁,一个数据库连接和一个ip socket.你可以获取他们通过:

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

但是有一个方法来做到这一块?喜欢的东西

with lock,db_con,socket:
   #do stuff

此外,它是可能的,因一系列未知的长度对象有方面的管理者,是否有可能以某种方式这样做:

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

如果回答是"没有",是因为需要这样的一个要素意味着糟糕的设计,或者也许我应该表明,它在一pep?:P

有帮助吗?

解决方案

蟒蛇2.7和3.1及以上, 你可以写:

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

这通常是最好的方法来使用,但是如果你有一个未知的长名单上下文经理,你会需要一个以下的方法。


蟒蛇3.3, 你可以输入一个未知的长名单上下文管理人员通过使用 contextlib.ExitStack:

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

这可以让你创造方面的管理人员因为你是增加他们的 ExitStack, ,这防止了可能的问题 contextlib.nested (下面将提到).

contextlib2 提供 一个移植的 ExitStack Python2.6和2.7.


蟒蛇2.6和下面, 你可以使用 contextlib.nested:

from contextlib import nested

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

相当于:

m1, m2, m3 = A(), B(), C()
with m1 as X:
    with m2 as Y:
        with m3 as Z:
            do_something()

注意,这并不是完全相同的,因为通常使用嵌套的 with, 因为 A(), B(), , C() 将所有被称为最初,在进入方面的管理人员。这将不会正常工作,如果这些功能之一提出了一个例外。

contextlib.nested 使用更新的蟒蛇版本在支持上述方法。

其他提示

第一部分的你的问题是可能的 蟒蛇3.1.

与多个项目,环境管理人员进行处理,如果多发言都嵌套:

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

相当于

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

改变在3.1版:支持多方面的表情

@interjay的答案是正确的。然而,如果您需要这样做长期下管理人员,例如模拟。修补下文经理,那你很快意识到你想要打破这种跨线。原来你可以不将它们包装在括号,所以你必须使用反斜杠。这是什么看起来像:

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

第二部分的你的问题就解决了 contextlib.ExitStack蟒蛇3.3.

以下从@sage88的响应你总是可以分配给那些贴有意义的变量名称在你进入他们。

你可以创建这些补丁在多条线

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()
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top