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‘)])
时间: 2024-08-03 07:04:46

python with魔法语句的相关文章

转: 理解Python的With语句

Python’s with statement provides a very convenient way of dealing with the situation where you have to do a setup and teardown to make something happen. A very good example for this is the situation where you want to gain a handler to a file, read da

Python 常用魔法方法(下)

Python 常用魔法方法(下) 回顾 魔法方法是 Python 内置方法, 不需要我们手动调用, 它存在的目的是给 解释器 调用的. 比如我们在写 "1 + 1 " 的时候, 这个 "+ " 就会自动调用内置的魔法方法 "__ add__" . 几乎每个魔法方法, 都有一个对应的内置函数或运算符. 当我们使用这些方法去操作数据时, 解释器会自动调用这些对应的魔法方法. 也可以理解为, 重写内置函数, 如果改变的话. 具体的魔法方法等. 可以去看

Python 的条件语句和循环语句

一.顺序结构 顺序结构是最简单的一种程序结构,程序按照语句的书写次序自上而下顺序执行. 二.分支控制语句 Python条件语句是通过一条或多条语句的执行结果(True或者False)来决定执行的代码块. 1.if 语句 Python中if语句的一般形式如下所示: if condition_1: statement_block_1 elif condition_2: statement_block_2 else: statement_block_3 如果 "condition_1" 为

Python While 循环语句

Python While循环语句 Python 编程中while语句用于循环执行程序,即在一些条件下,循环执行一些段程序,以处理需要重复处理的相同任务. 执行语句可以是单个语句或语句块. 判断条件可以是任何表达式,任何非零.或非空(null)的值均为true. 当判断条件假false时,循环结束. 实例: #!/usr/bin/python count = 0 while ( count < 9): print 'The count is:', count count = count +1 pr

理解python的with语句

有一些任务, 可能事先需要设置, 事后做清理工作. 对于这种场景, python的with语句提供了一种非常方变的处理方式, 一个很好的例子是文件处理. 你需要获取一个文件的句柄, 从文件中读取数据, 然后关闭文件句柄. 如果不用with语句, 代码如下: file = open("/tmp/foo.txt") data = file.read() file.close() 这里有两个比较烦人的地方, 一是可能忘记关闭句柄, 而是文件读取数据时发生异常, 却没有进行任何处理(文件读取数

Python的pass语句

Python pass是空语句,是为了保持程序结构的完整性.pass不做任何事情,一般用做占位语句. Python 语言 pass 语句语法格式如下: pass 示例代码: #!/usr/bin/env python # -*- coding:utf8 -*- for letter in 'python':     if letter == 'h':         pass         print '这是pass 块'     print '当前字母:',letter print "Goo

python中判断语句用两个or连接的奇葩

学python的时候犯的一个错误,放在这吧.就是在循环某个列表的时候不要去操作它,这是容易忽略的一个地方.所以如果要操作某个列表本身,那么先把该列表copy一份,然后再读取的时候读copy的那份.操作原来的列表. 正确的如下: import re a="hen/zg /zg qd/a /a ,/x /x hen/zg /zg xh/v /v " b=re.split('[ ]', a) b_copy=b[:] print b cixing=["/x","/

Python学习-6.Python的分支语句

Python的分支语句比较简单,只有if.else.elif三个关键字,也就是说,Python没有switch语句,而且,Python中并没有?:这个三目运算符. 例子: 1 age = 18 2 if age < 18: 3 print('too young') 4 elif age == 18: 5 print('ok') 6 else: 7 print('too old') 结果输出为ok

[转]python 里面 try语句

python 的异常 2010-11-03 22:36:36 python的try语句有两种风格 一:种是处理异常(try/except/else) 二:种是无论是否发生异常都将执行最后的代码(try/finally) try/except/else风格 try:     <语句> #运行别的代码 except <名字>:     <语句> #如果在try部份引发了'name'异常 except <名字>,<数据>:     <语句>