1、isinstance(obj, cls)python
检查是否obj是不是类 cls 的对象编程
class Foo(object): pass obj = Foo() isinstance(obj, Foo)
2、issubclass(sub, super)服务器
检查sub类是不是 super 类的派生类网络
class Foo(object): pass class Bar(Foo): pass issubclass(Bar, Foo)
3、异常处理socket
一、异常基础ide
在编程过程当中为了增长友好性,在程序出现bug时通常不会将错误信息显示给用户,而是现实一个提示的页面,通俗来讲就是不让用户看见大黄页!!!函数
二、异常种类编码
python中的异常种类很是多,每一个异常专门用于处理某一项异常!!!spa
1 AttributeError 试图访问一个对象没有的树形,好比foo.x,可是foo没有属性x 2 IOError 输入/输出异常;基本上是没法打开文件 3 ImportError 没法引入模块或包;基本上是路径问题或名称错误 4 IndentationError 语法错误(的子类) ;代码没有正确对齐 5 IndexError 下标索引超出序列边界,好比当x只有三个元素,却试图访问x[5] 6 KeyError 试图访问字典里不存在的键 7 KeyboardInterrupt Ctrl+C被按下 8 NameError 使用一个还未被赋予对象的变量 9 SyntaxError Python代码非法,代码不能编译(我的认为这是语法错误,写错了) 10 TypeError 传入对象类型与要求的不符合 11 UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是因为另有一个同名的全局变量, 12 致使你觉得正在访问它 13 ValueError 传入一个调用者不指望的值,即便值的类型是正确的
ArithmeticError AssertionError AttributeError BaseException BufferError BytesWarning DeprecationWarning EnvironmentError EOFError Exception FloatingPointError FutureWarning GeneratorExit ImportError ImportWarning IndentationError IndexError IOError KeyboardInterrupt KeyError LookupError MemoryError NameError NotImplementedError OSError OverflowError PendingDeprecationWarning ReferenceError RuntimeError RuntimeWarning StandardError StopIteration SyntaxError SyntaxWarning SystemError SystemExit TabError TypeError UnboundLocalError UnicodeDecodeError UnicodeEncodeError UnicodeError UnicodeTranslateError UnicodeWarning UserWarning ValueError Warning ZeroDivisionError
万能异常 在python的异常中,有一个万能异常:Exception,他能够捕获任意异常,即:code
接下来你可能要问了,既然有这个万能异常,其余异常是否是就能够忽略了!
答:固然不是,对于特殊处理或提醒的异常须要先定义,最后定义Exception来确保程序正常运行。
三、异常其余结构
1 try: 2 # 主代码块 3 pass 4 except KeyError,e: 5 # 异常时,执行该块 6 pass 7 else: 8 # 主代码块执行完,执行该块 9 pass 10 finally: 11 # 不管异常与否,最终执行该块 12 pass
四、主动触发异常
五、自定义异常
class WupeiqiException(Exception): def __init__(self, msg): self.message = msg def __str__(self): return self.message try: raise WupeiqiException('个人异常') except WupeiqiException,e: print e
六、断言
# assert 条件
assert 1 == 1
assert 1 == 2
4、反射
python中的反射功能是由如下四个内置函数提供:hasattr、getattr、setattr、delattr,改四个函数分别用于对对象内部执行:检查是否含有某成员、获取成员、设置成员、删除成员。
class Foo(object): def __init__(self): self.name = 'wupeiqi' def func(self): return 'func' obj = Foo() # #### 检查是否含有成员 #### hasattr(obj, 'name') hasattr(obj, 'func') # #### 获取成员 #### getattr(obj, 'name') getattr(obj, 'func') # #### 设置成员 #### setattr(obj, 'age', 18) setattr(obj, 'show', lambda num: num + 1) # #### 删除成员 #### delattr(obj, 'name') delattr(obj, 'func')
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1、概述
socket一般也称做"套接字",用于描述IP地址和端口,是一个通讯链的句柄,应用程序一般经过"套接字"向网络发出请求或者应答网络请求。
socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,对于文件用【打开】【读写】【关闭】模式来操做。 socket就是该模式的一个实现,socket便是一种特殊的文件,一些socket函数就是对其进行的操做(读/写IO、打开、关闭)
socket和file的区别:
WEB服务应用:
#!/usr/bin/env python #coding:utf-8 import socket def handle_request(client): buf = client.recv(1024) client.send("HTTP/1.1 200 OK\r\n\r\n") client.send("Hello, World") def main(): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.bind(('localhost',8080)) sock.listen(5) while True: connection, address = sock.accept() handle_request(connection) connection.close() if __name__ == '__main__': main()
2、解释
sk = socket.socket(socket.AF_INET,socket.SOCK_STREAM,0)
参数一:地址簇
socket.AF_INET IPv4(默认)
socket.AF_INET6 IPv6
socket.AF_UNIX 只可以用于单一的Unix系统进程间通讯
参数二:类型
socket.SOCK_STREAM 流式socket , for TCP (默认)
socket.SOCK_DGRAM 数据报式socket , for UDP
socket.SOCK_RAW 原始套接字,普通的套接字没法处理ICMP、IGMP等网络报文,而SOCK_RAW能够;其次,SOCK_RAW也能够处理特殊的IPv4报文;此外,利用原始套接字,能够经过IP_HDRINCL套接字选项由用户构造IP头。
socket.SOCK_RDM 是一种可靠的UDP形式,即保证交付数据报但不保证顺序。SOCK_RAM用来提供对原始协议的低级访问,在须要执行某些特殊操做时使用,如发送ICMP报文。SOCK_RAM一般仅限于高级用户或管理员运行的程序使用。
socket.SOCK_SEQPACKET 可靠的连续数据包服务
参数三:协议
0 (默认)与特定的地址家族相关的协议,若是是 0 ,则系统就会根据地址格式和套接类别,自动选择一个合适的协议
import socket ip_port = ('127.0.0.1',9999) sk = socket.socket(socket.AF_INET,socket.SOCK_DGRAM,0) sk.bind(ip_port) while True: data = sk.recv(1024) print data import socket ip_port = ('127.0.0.1',9999) sk = socket.socket(socket.AF_INET,socket.SOCK_DGRAM,0) while True: inp = raw_input('数据:').strip() if inp == 'exit': break sk.sendto(inp,ip_port) sk.close()
sk.bind(address)
s.bind(address) 将套接字绑定到地址。address地址的格式取决于地址族。在AF_INET下,以元组(host,port)的形式表示地址。
sk.listen(backlog)
开始监听传入链接。backlog指定在拒绝链接以前,能够挂起的最大链接数量。
backlog等于5,表示内核已经接到了链接请求,但服务器尚未调用accept进行处理的链接个数最大为5
这个值不能无限大,由于要在内核中维护链接队列
sk.setblocking(bool)
是否阻塞(默认True),若是设置False,那么accept和recv时一旦无数据,则报错。
sk.accept()
接受链接并返回(conn,address),其中conn是新的套接字对象,能够用来接收和发送数据。address是链接客户端的地址。
接收TCP 客户的链接(阻塞式)等待链接的到来
sk.connect(address)
链接到address处的套接字。通常,address的格式为元组(hostname,port),若是链接出错,返回socket.error错误。
sk.connect_ex(address)
同上,只不过会有返回值,链接成功时返回 0 ,链接失败时候返回编码,例如:10061
sk.close()
关闭套接字
sk.recv(bufsize[,flag])
接受套接字的数据。数据以字符串形式返回,bufsize指定最多能够接收的数量。flag提供有关消息的其余信息,一般能够忽略。
sk.recvfrom(bufsize[.flag])
与recv()相似,但返回值是(data,address)。其中data是包含接收数据的字符串,address是发送数据的套接字地址。
sk.send(string[,flag])
将string中的数据发送到链接的套接字。返回值是要发送的字节数量,该数量可能小于string的字节大小。
sk.sendall(string[,flag])
将string中的数据发送到链接的套接字,但在返回以前会尝试发送全部数据。成功返回None,失败则抛出异常。
sk.sendto(string[,flag],address)
将数据发送到套接字,address是形式为(ipaddr,port)的元组,指定远程地址。返回值是发送的字节数。该函数主要用于UDP协议。
sk.settimeout(timeout)
设置套接字操做的超时期,timeout是一个浮点数,单位是秒。值为None表示没有超时期。通常,超时期应该在刚建立套接字时设置,由于它们可能用于链接的操做(如 client 链接最多等待5s )
sk.getpeername()
返回链接套接字的远程地址。返回值一般是元组(ipaddr,port)。
sk.getsockname()
返回套接字本身的地址。一般是一个元组(ipaddr,port)
sk.fileno()
套接字的文件描述符
1、使用以源码剖析
对于默认Socket服务端处理客户端请求时,按照阻塞方式依次处理请求,SocketServer实现同事处理多个请求。
#!/usr/bin/env python #coding:utf-8 import SocketServer import os class MyServer(SocketServer.BaseRequestHandler): def handle(self): base_path = 'G:/temp' conn = self.request print 'connected...' while True: pre_data = conn.recv(1024) #获取请求方法、文件名、文件大小 cmd,file_name,file_size = pre_data.split('|') # 防止粘包,给客户端发送一个信号。 conn.sendall('nothing') #已经接收文件的大小 recv_size = 0 #上传文件路径拼接 file_dir = os.path.join(base_path,file_name) f = file(file_dir,'wb') Flag = True while Flag: #未上传完毕, if int(file_size)>recv_size: #最多接收1024,可能接收的小于1024 data = conn.recv(1024) recv_size+=len(data) #写入文件 f.write(data) #上传完毕,则退出循环 else: recv_size = 0 Flag = False print 'upload successed.' f.close() instance = SocketServer.ThreadingTCPServer(('127.0.0.1',9999),MyServer) instance.serve_forever()
#!/usr/bin/env python #coding:utf-8 import socket import sys import os ip_port = ('127.0.0.1',9999) sk = socket.socket() sk.connect(ip_port) container = {'key':'','data':''} while True: # 客户端输入要上传文件的路径 input = raw_input('path:') # 根据路径获取文件名 file_name = os.path.basename(path) # 获取文件大小 file_size=os.stat(path).st_size # 发送文件名 和 文件大小 sk.send(file_name+'|'+str(file_size)) # 为了防止粘包,将文件名和大小发送过去以后,等待服务端收到,直到从服务端接受一个信号(说明服务端已经收到) sk.recv(1024) send_size = 0 f= file(path,'rb') Flag = True while Flag: if send_size + 1024 >file_size: data = f.read(file_size-send_size) Flag = False else: data = f.read(1024) send_size+=1024 sk.send(data) f.close() sk.close()
对于大文件处理:
send只会向缓冲区写一次,传入的内容不必定能发完,因此,返回值是实际发送的大小。 例如: 1023M = send(1g数据) 那么实际是发送了 1023M,其余 1M 就是漏发了 sendall,内部调用send会一直向缓冲区写,直到文件所有写完。 例如: sendall(1g数据) 第一次: send(1023M) 第二次: send(1M) ========== 发送大文件时候,不可能所有读1G内存,须要open文件时,一点一点读,而后再发。 # 大文件大小 file_size=os.stat(文件路径).st_size # 打开大文件 f = file(文件路径,'rb') # 已经发送的数据 send_size = 0 while Flag: # 大文件只剩下 不到 1024 字节,其余已经被发送。 if send_size + 1024 > file_size: # 从大文件中读取小于 1024字节,多是 10字节... data = f.read(file_size-send_size) Flag = False else: # 从大文件中读取 1024 字节 data = f.read(1024) # 记录已经发送了多少字节 send_size += 1024 # 将大文件中的数据,分批发送到缓冲区,每次最多发 1024 字节 sk.sendall(data)