python with魔法语句

简介:

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

1
2
3
4
5
file  =  open ( "a.txt" )
try :  
   data  =  file .read()
finally :    
    file .close()

*每一个打开文件之后要关闭文件描述符,但是使用with语句则不用:

1
2
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__函数:


写一个类似打开文件的操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/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时候表示会抛出异常。


提示异常操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/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" )

执行效果:

1
2
3
4
5
6
[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监听端口打数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#!/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' )])









本文转自 小罗ge11 51CTO博客,原文链接:http://blog.51cto.com/xiaoluoge/1760484,如需转载请自行联系原作者
目录
打赏
0
0
0
0
234
分享
相关文章
Python 数据库Insert语句脚本生成工具(SQL Server)
Python 数据库Insert语句脚本生成工具(SQL Server)
398 0
Python 数据库Insert语句脚本生成工具(SQL Server)
python基础 判断语句
python基础 判断语句
145 0
python基础 判断语句
PandaSQL:一个让你能够通过SQL语句进行pandas的操作的python包
PandaSQL:一个让你能够通过SQL语句进行pandas的操作的python包
665 0
PandaSQL:一个让你能够通过SQL语句进行pandas的操作的python包
Python学习笔记第二天(Python基本语句)
Python学习笔记第二天讲解行与缩进 关键字 数据类型的用法。
124 0
Python学习笔记第二天(Python基本语句)
Pyhton学习笔记第一天(Python基本语句)
Python学习笔记第一天讲解注释、输出、标识符、多行语句的用法。
119 0
Pyhton学习笔记第一天(Python基本语句)
Python 条件控制 — if语句
生活中的判断几乎是无所不在的,我们每天都在做各种各样的选择,如果这样?如果那样?……
Python中的While 语句
Python中的While 语句自制脑图
100 0
Python中的While 语句
Python中的if-elif-else 语句
Python中的if-elif-else 语句自制脑图
87 0
Python中的if-elif-else 语句
Python中的if-else 语句
Python中的if-else 语句自制脑图 if-else 语句的相关代码,if-else 语句语法,执行流程
95 0
Python中的if-else 语句

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等