Python学习心路历程-day7

学习内容:

1.类的特殊成员方法

2.反射

3.异常处理

4.Socket网络编程开发基础

 

1.类的特殊成员方法                                                                           

__doc__ 表示类的描述信息

  1 # _*_ coding:utf-8 _*_
  2 __author__ = 'cs'
  3 class Foo:
  4     """类的描述信息,就是__doc__"""
  5     def func(self):
  6         pass
  7 print Foo.__doc__
__module__ 和  __class__ 

  __module__ 表示当前操作的对象在那个模块

  __class__     表示当前操作的对象的类是什么

__init__ 构造方法,通过类创建对象时,自动触发执行。

__del__

析构方法,当对象在内存中被释放时,自动触发执行。

注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。

__call__ 对象后面加括号,触发执行

注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()

  1 #__call__
  2 # 注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()
  3 class Dog:
  4     def __init__(self,name):
  5         self.name = name
  6     def bulk(self):
  7         print("%s 汪~汪~汪" %(self.name))
  8     def __call__(self, *args, **kwargs):
  9         print "I am call",args,kwargs
 10 d1 = Dog("旺旺")
 11 d1("aaa","bbb","cccc")

__dict__ 查看类或对象中的所有成员

  1 # _*_ coding:utf-8 _*_
  2 __author__ = 'cs'
  3 class Province:
  4     country = 'China'
  5     def __init__(self, name, count):
  6         self.name = name
  7         self.count = count
  8     def func(self, *args, **kwargs):
  9         print 'func'
 10 # 获取类的成员,即:静态字段、方法、
 11 print Province.__dict__
 12 # obj1 = Province('HuBei',10000)
 13 # print obj1.__dict__
 14 # 获取 对象obj1 的成员
 15 obj2 = Province('HuNan', 3888)
 16 # print obj2.__dict__
 17 # 获取 对象obj1 的成员

__str__ 如果一个类中定义了__str__方法,那么在打印对象时,默认输出该方法的返回值。

python3中使用,python建议使用__unicode__

  1 # _*_ coding:utf-8 _*_
  2 __author__ = 'cs'
  3 class Role(object):
  4     def __init__(self,name,role,weapon,life_value=100,money=15000):
  5         self.name = name
  6         self.role = role
  7         self.weapon = weapon
  8         self.life_value = life_value
  9         self.money = money
 10     def shot(self):
 11         print("shooting...")
 12     def got_shot(self):
 13         print("%s: ah...,I got shot..."%self.name)
 14     def buy_gun(self,gun_name):
 15         print("just bought %s" %gun_name)
 16     # def __str__(self):
 17     #     print("name is %s"%self.name)
 18     #     return "name is %s"%self.name
 19
 20 r1 = Role("A","P","Ak47")
 21 print(r1)

__getitem____setitem____delitem__

用于索引操作,如字典。以上分别表示获取、设置、删除数据

  1 # _*_ coding:utf-8 _*_
  2 __author__ = 'cs'
  3 #把这个实例变成字典
  4 class Foo(object):
  5     def __init__(self):
  6         self.data = {}
  7     def __getitem__(self, key):
  8         print('__getitem__',key)   #('__getitem__', 'name')
  9         return self.data.get(key)
 10     def __setitem__(self, key, value):
 11         print('__setitem__',key,value)
 12         self.data[key] = value
 13     def __delitem__(self, key):
 14         print('__delitem__',key)
 15
 16
 17 obj = Foo()   #实例化后,就成了字典
 18 obj["name"] = "lw"  #可以像字典一样赋值,自动触发执行 __setitem__
 19 result = obj['name']      # 自动触发执行 __getitem__
 20 print(result)
 21 print(obj.data)    #打印这个字典
 22 del obj['name']    #只是触发__delitem__,并没有真的删除,要想删除在__delitem__这个函数下面删除,如果不想让用户删除某些key,可以加判断
 23 print(obj.data)
 24 # del obj['k1']

2.反射                                                                                              

通过字符串映射或修改程序运行时的状态、属性、方法, 有以下4个方法

hasattr:判断object中有没有一个name字符串对应的方法或属性

getattr:根据字符串去获取对象里的方法对应的内存地址

setattr :s equivalent to ``x.y = v''

delattr(x, y)

例1:

  1 # _*_ coding:utf-8 _*_
  2 __author__ = 'cs'
  3 def bulk(self):   #这里会将函数设置成类里面的方法
  4     print("%s is bulking"%self.name)
  5 class Dog(object):
  6
  7     def __init__(self,name):
  8         self.name = name
  9     def eat(self,age):
 10
 11         print("%s is eating.."%self.name)
 12
 13 d = Dog("金毛")
 14 # d.eat()
 15 choice = raw_input(">>>:").strip()
 16 # d.choice  想实现这种调用,根据用户输入调用方法,但是不能这么写,因为choic是个字符串
 17 print(hasattr(d,choice))    #查看类中是否有用户输入的方法或者属性,有打印True,没有打印False
 18 # print(getattr(d,choice))    #这样会打印这个方法的内存地址,加上()就调用了
 19 # getattr(d,choice)()        #调用
 20 #------------------------------
 21 # print(d.name)
 22 # setattr(d,"name",choice)
 23 # print(d.name)
 24 #-------------------------------
 25 # setattr(d,choice,"22")
 26 # print(getattr(d,choice))
 27 # print(hasattr(d,choice))
 28 #------------------------------
 29 #动态添加变量
 30 # if hasattr(d,choice):
 31 #     getattr(d,choice)
 32 # else:
 33 #     setattr(d,choice,"ccc")
 34 #     V = getattr(d,choice)
 35 #     print(V)
 36 #---------------------------
 37 #动态设置方法,无论用户输入什么,都不会报错,都可以调用方法
 38 # if hasattr(d,choice):
 39 #     getattr(d,choice)
 40 # else:
 41 #     setattr(d,choice,bulk)   #d.talk == bulk
 42 #     func = getattr(d,choice)   #获取choic的内存地址
 43 #     func(d)
 44
 45 # ----------------------
 46 # print(hasattr(d,choice))
 47 # getattr(d,choice)()
 48 # print(d.name)
 49 # if hasattr(d,choice):
 50 #     delattr(d,choice)
 51 # else:
 52 #     print("dont")
 53 # print(d.name)
 54 # delattr(d,choice)
 55 # if hasattr(d,choice):
 56 #     getattr(d,choice)()
 57 #
 58 # else:
 59 #     # print("没有这个方法")

例2:

  1 class Foo(object):
  2 
  3     def __init__(self):
  4         self.name = 'wupeiqi'
  5 
  6     def func(self):
  7         return 'func'
  8 
  9 obj = Foo()
 10 
 11 # #### 检查是否含有成员 ####
 12 hasattr(obj, 'name')
 13 hasattr(obj, 'func')
 14 
 15 # #### 获取成员 ####
 16 getattr(obj, 'name')
 17 getattr(obj, 'func')
 18 
 19 # #### 设置成员 ####
 20 setattr(obj, 'age', 18)
 21 setattr(obj, 'show', lambda num: num + 1)
 22 
 23 # #### 删除成员 ####
 24 delattr(obj, 'name')
 25 delattr(obj, 'func')
View Code

例3:

  1 # __author__ = 'cs'
  2 def dulk():
  3     print("%s is ...")
  4 class Dog(object):
  5     def __init__(self,name):
  6         self.name = name
  7     def eat(self):
  8         print("%s is eating..." %self.name)
  9 d = Dog("niuhanyang")
 10 choice = input(">>:").strip()    #输入的是Dog这个类里面的方法---->eat
 11 if hasattr(d,choice):            #判断choice(输入的)字符串在d(类)里面是否存在
 12     #print(getattr(d,choice))      #获取方法并打印
 13     getattr(d,choice)()           #获取方法并执行
 14 else:
 15     setattr(d,choice,dulk)            #d.choice = dulk的内存地址
 16     fun = getattr(d,choice)
 17     fun()
View Code

3.异常处理                                                                                        

参考 http://www.cnblogs.com/wupeiqi/articles/5017742.html 

1、异常基础

在编程过程中为了增加友好性,在程序出现bug时一般不会将错误信息显示给用户,而是现实一个提示的页面,通俗来说就是不让用户看见大黄页!!!

  1 try:
  2     pass
  3 except Exception,ex:
  4     pass

需求:将用户输入的两个数字相加

  1 while True:
  2     num1 = raw_input('num1:')
  3     num2 = raw_input('num2:')
  4     try:
  5         num1 = int(num1)
  6         num2 = int(num2)
  7         result = num1 + num2
  8     except Exception, e:
  9         print '出现异常,信息如下:'
 10         print e
View Code

2、异常种类

python中的异常种类非常多,每个异常专门用于处理某一项异常!!!

  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 传入一个调用者不期望的值,即使值的类型是正确的
常用异常
  1 ArithmeticError
  2 AssertionError
  3 AttributeError
  4 BaseException
  5 BufferError
  6 BytesWarning
  7 DeprecationWarning
  8 EnvironmentError
  9 EOFError
 10 Exception
 11 FloatingPointError
 12 FutureWarning
 13 GeneratorExit
 14 ImportError
 15 ImportWarning
 16 IndentationError
 17 IndexError
 18 IOError
 19 KeyboardInterrupt
 20 KeyError
 21 LookupError
 22 MemoryError
 23 NameError
 24 NotImplementedError
 25 OSError
 26 OverflowError
 27 PendingDeprecationWarning
 28 ReferenceError
 29 RuntimeError
 30 RuntimeWarning
 31 StandardError
 32 StopIteration
 33 SyntaxError
 34 SyntaxWarning
 35 SystemError
 36 SystemExit
 37 TabError
 38 TypeError
 39 UnboundLocalError
 40 UnicodeDecodeError
 41 UnicodeEncodeError
 42 UnicodeError
 43 UnicodeTranslateError
 44 UnicodeWarning
 45 UserWarning
 46 ValueError
 47 Warning
 48 ZeroDivisionError
 49 
 50 更多异常
更多异常
  1 dic = ["wupeiqi", 'alex']
  2 try:
  3     dic[10]
  4 except IndexError, e:
  5     print e
实例:IndexError
  1 dic = {'k1':'v1'}
  2 try:
  3     dic['k20']
  4 except KeyError, e:
  5     print e
实例:KeyError
  1 s1 = 'hello'
  2 try:
  3     int(s1)
  4 except ValueError, e:
  5     print e
实例:ValueError

对于上述实例,异常类只能用来处理指定的异常情况,如果非指定异常则无法处理。

  1 # 未捕获到异常,程序直接报错
  2 
  3 s1 = 'hello'
  4 try:
  5     int(s1)
  6 except IndexError,e:
  7     print e
View Code

所以,写程序时需要考虑到try代码块中可能出现的任意异常,可以这样写:

  1 s1 = 'hello'
  2 try:
  3     int(s1)
  4 except IndexError,e:
  5     print e
  6 except KeyError,e:
  7     print e
  8 except ValueError,e:
  9     print e
View Code

万能异常 在python的异常中,有一个万能异常:Exception,他可以捕获任意异常,即:

  1 s1 = 'hello'
  2 try:
  3     int(s1)
  4 except Exception,e:
  5     print e
View Code

接下来你可能要问了,既然有这个万能异常,其他异常是不是就可以忽略了!

答:当然不是,对于特殊处理或提醒的异常需要先定义,最后定义Exception来确保程序正常运行。

  1 s1 = 'hello'
  2 try:
  3     int(s1)
  4 except KeyError,e:
  5     print '键错误'
  6 except IndexError,e:
  7     print '索引错误'
  8 except Exception, e:
  9     print '错误'
View Code

3、异常其他结构

  1 try:
  2     # 主代码块
  3     pass
  4 except KeyError,e:
  5     # 异常时,执行该块
  6     pass
  7 else:
  8     # 主代码块执行完,执行该块
  9     pass
 10 finally:
 11     # 无论异常与否,最终执行该块
 12     pass
View Code

4、主动触发异常

  1 try:
  2     raise Exception('错误了。。。')
  3 except Exception,e:
  4     print e
View Code

5、自定义异常

  1 class WupeiqiException(Exception):
  2 
  3     def __init__(self, msg):
  4         self.message = msg
  5 
  6     def __str__(self):
  7         return self.message
  8 
  9 try:
 10     raise WupeiqiException('我的异常')
 11 except WupeiqiException,e:
 12     print e
View Code

6、断言

  1 # assert 条件
  2 
  3 assert 1 == 1
  4 
  5 assert 1 == 2
View Code

4.Socket网络编程开发基础                                                                

参考:http://www.cnblogs.com/wupeiqi/articles/5040823.html

socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求。

socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,对于文件用【打开】【读写】【关闭】模式来操作。socket就是该模式的一个实现,socket即是一种特殊的文件,一些socket函数就是对其进行的操作(读/写IO、打开、关闭)

socket和file的区别:

  • file模块是针对某个指定文件进行【打开】【读写】【关闭】
  • socket模块是针对 服务器端 和 客户端Socket 进行【打开】【读写】【关闭】

socket server:

  1 #-*-coding:utf-8-*-
  2 #服务器端
  3 
  4 import socket
  5 server = socket.socket()
  6 server.bind(('localhost',6969)) #绑定要监听端口
  7 server.listen(5) #监听
  8 
  9 print("我要开始等电话了")
 10 while True:
 11     conn, addr = server.accept()  # 等电话打进来
 12     # conn就是客户端连过来而在服务器端为其生成的一个连接实例
 13     print(conn, addr)
 14     print("电话来了")
 15     count = 0
 16     while True:
 17         data = conn.recv(1024)
 18         print("recv:",data)
 19         if not data:
 20             print("client has lost...")
 21             break
 22         conn.send(data.upper())
 23         count+=1
 24         if count >10:break
 25 
 26 server.close()

socket client:

  1 #客户端
  2 import socket
  3 
  4 client = socket.socket() #声明socket类型,同时生成socket连接对象
  5 client.connect(('localhost',6969))
  6 
  7 while True:
  8     msg = input(">>:").strip()
  9     if len(msg) == 0:continue
 10     client.send(msg.encode("utf-8"))
 11     data = client.recv(10240)
 12     print("recv:",data.decode())
 13 
 14 client.close()

WEB服务应用:

  1 #!/usr/bin/env python
  2 #coding:utf-8
  3 import socket
  4 
  5 def handle_request(client):
  6     buf = client.recv(1024)
  7     client.send("HTTP/1.1 200 OK\r\n\r\n")
  8     client.send("Hello, World")
  9 
 10 def main():
 11     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 12     sock.bind(('localhost',8080))
 13     sock.listen(5)
 14 
 15     while True:
 16         connection, address = sock.accept()
 17         handle_request(connection)
 18         connection.close()
 19 
 20 if __name__ == '__main__':
 21   main()

更多功能

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 ,则系统就会根据地址格式和套接类别,自动选择一个合适的协议

  1 import socket
  2 ip_port = ('127.0.0.1',9999)
  3 sk = socket.socket(socket.AF_INET,socket.SOCK_DGRAM,0)
  4 sk.bind(ip_port)
  5 
  6 while True:
  7     data = sk.recv(1024)
  8     print data
  9 
 10 
 11 
 12 
 13 import socket
 14 ip_port = ('127.0.0.1',9999)
 15 
 16 sk = socket.socket(socket.AF_INET,socket.SOCK_DGRAM,0)
 17 while True:
 18     inp = raw_input('数据:').strip()
 19     if inp == 'exit':
 20         break
 21     sk.sendto(inp,ip_port)
 22 
 23 sk.close()
 24 
UDP Demo

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,失败则抛出异常。

      内部通过递归调用send,将所有内容发送出去。

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

  套接字的文件描述符

转载于:https://www.cnblogs.com/cs-qzyy/p/8717533.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值