with语法
会话管理,在Python 2.5中,为了代码利用定义了一个新的关键词 with 语句。会话控制在Python中不罕见(之前是作为库的一部分被实现),直到 PEP343 被添加后。它被成为一级语言结构
原理
会话控制器通过包装一个 with 语句来设置和清理行为。回话控制器的行为通过两个魔术方法来定义: __enter__和__exit__
__enter__(self)
定义当使用 with 语句的时候会话管理器应该初始块被创建的时候的行为。注意 enter 的返回值被 with 语句的目标或者 as 后的名字绑定
__exit__(self, exception_type, exception_value, traceback)
定义当一个代码块被执行或者终止后会话管理器应该做什么。它可以被用来处理异常,清除工作或者做一些代码块执行完毕之后的日常工作。如果代码块执行成功, exception_type , exception_value , 和 traceback 将会是 None 。否则的话你可以选择处理这个异常或者是直接交给用户处理。如果你想处理这个异常的话,确认 exit 在所有结束之后会返回 True 。如果你想让异常被会话管理器处理的话,那么就这样处理,则可以像示例那样处理
- 使用示例
1
class Closer:
2
'''通过with语句和一个close方法来关闭一个对象的会话管理器'''
3
4
def __init__(self, obj):
5
self.obj = obj
6
7
def __enter__(self):
8
return self.obj # bound to target
9
10
def __exit__(self, exception_type, exception_val, trace):
11
try:
12
self.obj.close()
13
except AttributeError: # obj isn't closable
14
print('Not closable.')
15
return True # exception handled successfully
16
17
if __name__ == '__main__':
18
# file = open('queue_test.py')
19
# wt = Closer(file)
20
# print(wt.obj.read())
21
# wt.obj.close()
22
23
# 该用法和上面的代码用法等同,但是看起来更简洁with提高了代码精炼度
24
with Closer(open('queue_test.py')) as ob:
25
s = ob.read()
26
print(s)
__getitem__
只要是在类中定义了这个方法,就可以用类对象通过[]运算符进行访问,例如数组就可以通过这种方式直接访问下标对应的元素。
1 | class MyObject: |
2 | def __getitem__(self, item): |
3 | return '😘❤️' |
4 | |
5 | # 当用[]取值的时候会触发__getitem__函数调用 |
6 | print(MyObject()['name']) |
__setitem__
在对[]运算操作赋值时,会触发这个方法调用,比如我们直接对数组下标赋值,修改元素
1 | class MyObject: |
2 | def __getitem__(self, item): |
3 | return '😘❤️' |
4 | def __setitem__(self, key, value): |
5 | print(key,value) |
6 | |
7 | obj = MyObject() |
8 | print(obj['name']) |
9 | # 当给[]赋值时,会触发__setitem__调用 |
10 | obj[89] = 'qwer' |
__len__
一般用于需要计算长度的类会去重写这个方法
1 | class MyObject: |
2 | def __len__(self): |
3 | return 45 |
4 | |
5 | obj = MyObject() |
6 | print(len(obj)) |