python with魔法语句
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python with魔法语句相关的知识,希望对你有一定的参考价值。
通常之前我们在打开文件的时候都是:
file = open("a.txt") try: data = file.read() finally: file.close()
*每一个打开文件之后要关闭文件描述符,但是使用with语句则不用:
whih open("a.txt") as f: print f.readline()
这个是with默认封装的好的一个魔法盒子,封装了__enter__和__exit__两个函数:
为了我们自己的类也可以使用with, 只要给这个类增加两个函数__enter__, __exit__即可:
>>> class A:
... def __enter__(self):
... print "in enter"
... def __exit__(self, a, b, c):
... print "in exit"
>>> with A() as a:
... print "in with"
...
in enter
in with
in exit
*可以看到当我们使用with的适合最先调用的是__enter__函数,然后进行下面的操作,结束之后才到__exit__函数:
写一个类似打开文件的操作:
#!/usr/bin/env python class demo: def __init__(self, path, mode): self.path = path self.mode = mode def __enter__(self): return self def write(self, text): print self.path,self.mode print(text) def __exit__(self, a, b ,c): return True with demo("attr.py","w") as f: f.write("hello world") 执行效果: [[email protected] python]# python test_with.py attr.py w hello world
*这里把打开文件读取,转换成打印传入的参数和执行with里面write函数的操作。
__exit__方法里面的,a,b,c分别表示:异常类型如value.Error、异常描述、Traceback;当使用return True 时候表示会捕获异常,return False时候表示会抛出异常。
提示异常操作:
#!/usr/bin/env python class demo: def __init__(self, path, mode): self.path = path self.mode = mode def __enter__(self): return self def write(self, text): print self.path,self.mode print(text) def __exit__(self, a, b ,c): print a print b print c return True with demo("a.py","w") as f: f.write("hello world") int("error")
执行效果:
[[email protected] python]# python test_with.py a.py w hello world <type ‘exceptions.ValueError‘> invalid literal for int() with base 10: ‘error‘ <traceback object at 0xb3e3f8>
这样with可以帮助我们完成很多重复操作,比如初始化,连接数据库,关闭数据库;socket等多个重复操作。
举例用with语法往graphite的socker监听端口打数据。
#!/usr/bin/python # coding:utf-8 import errno import time import socket class CarbonClient(object): def __init__(self, host, port): self._host = host self._port = port self._carbon = None self._connected = None def connect(self): """ 建立socket连接 """ if not self._connected: self._connect() def connected(self): return self._connected def _connect(self): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) while 1: try: sock.connect((self._host, self._port)) except socket.error as e: if e.errno == errno.EINTR: continue else: raise e break self._carbon = sock self._connected = True def close(self): if self._connected: self._carbon.close() self._connected = False def send(self, metrics): chunk_start, chunk_end = 0,20 while 1: payload = [] metrics_chunk = metrics[chunk_start: chunk_end] if not metrics_chunk: break for metric in metrics_chunk: if len(metric) == 2: payload.append("{} {} {}\n".format(metric[0], metric[1], int(time.time()))) elif len(metric) == 3: payload.append("{} {} {}\n".format(*metric)) else: raise ValueError("Error format data") self._carbon.sendall("".join(payload)) chunk_start, chunk_end = chunk_end, chunk_end + 20 def __enter__(self): self.connect() return self def __exit__(self, exec_type, exec_value, exc_tb): self.close() return exec_value is None class RebootCarbonClient(CarbonClient): REBOOT_CARBON_ADDR = ("192.168.1.54", 2003) def __init__(self): super(RebootCarbonClient, self).__init__(*self.REBOOT_CARBON_ADDR) """ 1条: (key, value, time) (key, value) 多条 [(key, value), (key, value)] graphite api """ if __name__ == "__main__": with RebootCarbonClient() as client: client.send([("hostname.sys.mem.usage", ‘1096‘), ("hostname.sys.mem.usage", ‘2048‘)])
本文出自 “小罗” 博客,请务必保留此出处http://xiaoluoge.blog.51cto.com/9141967/1760484
以上是关于python with魔法语句的主要内容,如果未能解决你的问题,请参考以下文章