文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

python with魔法语句

2023-01-31 04:34

关注

通常之前我们在打开文件的时候都是:

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")

执行效果:
[root@monitor 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")

执行效果:

[root@monitor 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')])



阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯