在上下文管理器 (with) 和异常处理程序中使用 as 分配给成员
Assigning to a member with `as` in context-manager (with) and exception handler
首先,如果我没有使用正确的名称,我想道歉,我是 Python 的新手。
在玩游戏时我发现您可以在 with
语句的 as
部分分配给 class 成员:
from contextlib import contextmanager
@contextmanager
def func(val):
yield val*2
class Foo:
def __init__(self):
self.val = "Placeholder"
def bar(self):
with func(333) as self.val:
print("Got", self.val)
if __name__ == "__main__":
f = Foo()
print("Before:", f.val)
f.bar()
print("After:", f.val)
输出:
Before: Placeholder
Got 666
After: 666
但是,分配给 except
中的成员会出现语法错误:
class Foo:
def __init__(self):
self.err = None
def bar(self):
try:
os.remove(path)
except FileNotFoundError as self.err:
print("Couldn't remove", path)
输出:
except FileNotFoundError as self.err:
^
SyntaxError: invalid syntax
由于搜索 as
是徒劳的,我无法找到任何参考资料,我的问题是:
- 在
with
语句的 as
部分分配给成员的定义是否明确?
- 如果是,为什么异常处理不允许?
编辑:我想关于 import
...
可以问类似的问题
在except
clause, as
can only assign to an identifier. In a with
clause中,as
可以分配给任意目标。
try1_stmt ::= "try" ":" suite
("except" [expression ["as" identifier]] ":" suite)+
["else" ":" suite]
["finally" ":" suite]
with_item ::= expression ["as" target]
一个target是一个标识符(foo
),一个属性(foo.bar
),一个切片(foo[:bar]
),一个订阅(foo[bar]
), 上面的 list/tuple (foo, bar
) 或上面的 splat (*foo
).
异常会在其异常处理程序后自动清除。在处理程序后使用名称表明它已被删除:
>>> a = 1
>>> try:
... 1/0
... except ZeroDivisionError as a:
... pass
... print(a)
NameError: name 'a' is not defined
这避免了异常、引发异常的框架和绑定异常的名称之间不必要的引用循环。
直接绑定到另一个名称空间需要选择以下两种情况之一:
- 属性在处理程序之后被删除。这意味着物体的外观不一致。
- 处理程序后未删除该属性。这意味着除非手动清除,否则框架将无限期存在。
这两种变体都需要在处理程序之外显式处理异常。此外,它们很容易意外触发需要在其他地方进行显式处理的情况。
首先,如果我没有使用正确的名称,我想道歉,我是 Python 的新手。
在玩游戏时我发现您可以在 with
语句的 as
部分分配给 class 成员:
from contextlib import contextmanager
@contextmanager
def func(val):
yield val*2
class Foo:
def __init__(self):
self.val = "Placeholder"
def bar(self):
with func(333) as self.val:
print("Got", self.val)
if __name__ == "__main__":
f = Foo()
print("Before:", f.val)
f.bar()
print("After:", f.val)
输出:
Before: Placeholder
Got 666
After: 666
但是,分配给 except
中的成员会出现语法错误:
class Foo:
def __init__(self):
self.err = None
def bar(self):
try:
os.remove(path)
except FileNotFoundError as self.err:
print("Couldn't remove", path)
输出:
except FileNotFoundError as self.err: ^
SyntaxError: invalid syntax
由于搜索 as
是徒劳的,我无法找到任何参考资料,我的问题是:
- 在
with
语句的as
部分分配给成员的定义是否明确? - 如果是,为什么异常处理不允许?
编辑:我想关于 import
...
在except
clause, as
can only assign to an identifier. In a with
clause中,as
可以分配给任意目标。
try1_stmt ::= "try" ":" suite ("except" [expression ["as" identifier]] ":" suite)+ ["else" ":" suite] ["finally" ":" suite] with_item ::= expression ["as" target]
一个target是一个标识符(foo
),一个属性(foo.bar
),一个切片(foo[:bar]
),一个订阅(foo[bar]
), 上面的 list/tuple (foo, bar
) 或上面的 splat (*foo
).
异常会在其异常处理程序后自动清除。在处理程序后使用名称表明它已被删除:
>>> a = 1
>>> try:
... 1/0
... except ZeroDivisionError as a:
... pass
... print(a)
NameError: name 'a' is not defined
这避免了异常、引发异常的框架和绑定异常的名称之间不必要的引用循环。
直接绑定到另一个名称空间需要选择以下两种情况之一:
- 属性在处理程序之后被删除。这意味着物体的外观不一致。
- 处理程序后未删除该属性。这意味着除非手动清除,否则框架将无限期存在。
这两种变体都需要在处理程序之外显式处理异常。此外,它们很容易意外触发需要在其他地方进行显式处理的情况。