python中的"with"语句,为什么"as"部分必须是单个对象

Ale*_*eal 6 python with-statement contextmanager

使用Python可以说:

a,b,c=something_that_returns_a_3_tuple()
Run Code Online (Sandbox Code Playgroud)

但是with声明如下:

class thing(object):
    def __enter__(self):
        return (1,2,3)

    def __exit__(self,a,b,c):
        pass

with thing() as a,b,c:
    print a
    print b 
    print c
Run Code Online (Sandbox Code Playgroud)

不会工作

必须有:

class thing(object):
    def __enter__(self):
        return (1,2,3)

    def __exit__(self,a,b,c):
        pass

with thing() as (a,b,c):
    print a
    print b 
    print c
Run Code Online (Sandbox Code Playgroud)

我不能看到允许第一个表单的实际问题,通过这个我的意思是实现或逻辑,解析器不应该有逗号的问题(它不会模棱两可),我认为没有逻辑原因为什么不.

http://docs.python.org/release/2.5/whatsnew/pep-343.html

http://www.python.org/dev/peps/pep-0343/表明这只是合成糖

Mar*_*ers 26

您不能在语法中使用没有括号的元组目标,因为否则您无法区分多个上下文管理器:

with contextmanager1 as target1, contextmanager2 as target2:
Run Code Online (Sandbox Code Playgroud)

看到那里的逗号?由于语法允许指定多个上下文管理器,因此编译器无法区分该表单和仅使用逗号指定的多个目标.

啊,你说,但那里有as target2一部分,不能用来区分形式吗?然后记住,目标是可选的.以下是完全合法的语法:

with contextmanager1 as target1, contextmanager2:
Run Code Online (Sandbox Code Playgroud)

Python知道逗号之后的部分是另一个上下文管理器,因为它不允许多个目标没有括号,删除所有歧义.

PEP 343实施后,在Python 2.7和3.1中引入了对多个上下文管理器的支持.但是,PEP 确实预见到了这种可能性:

此限制使语法的未来扩展可能具有多个以逗号分隔的资源,每个资源都有自己的可选as-clause.