6

使用 Python 可以说:

a,b,c=something_that_returns_a_3_tuple()

但是这样的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

行不通

必须具备:

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

我看不出允许第一种形式的实际问题,我的意思是实现或逻辑,解析器不应该有逗号问题(它不会模棱两可),我看不出有什么合乎逻辑的理由。

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

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

4

1 回答 1

27

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

with contextmanager1 as target1, contextmanager2 as target2:

看到那里的逗号了吗?因为语法允许指定多个上下文管理器,所以编译器无法区分该形式和仅用逗号指定的多个目标。

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

with contextmanager1 as target1, contextmanager2:

Python 知道逗号后面的部分是那里的另一个上下文管理器,因为它不允许没有括号的多个目标,从而消除了所有歧义。

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

此限制使将来的语法扩展成为可能,以具有多个以逗号分隔的资源,每个资源都有自己的可选 as 子句。

于 2013-12-14T22:01:02.330 回答