大纲
一、面向对象高级语法
1.静态方法、类方法、属性方法
2.类的特殊成员方法
3.反射
二、异常处理
三、网络编程之socket基础
一、面向对象高级语法
1.静态方法:名义上归类管理,实际上静态方法里访问不了类或者实例中的任何属性
# _*_ coding:utf-8 _*_ __author__ = "ZingP" class Dog(object): def __init__(self,name): self.name = name @staticmethod # 实际上跟类没什么关系 def eat(): print("%s is eating.." % "hehe") d = Dog("Baker") d.eat() # 运行结果:hehe is eating.. # 如果改成这样: # @staticmethod # 实际上跟类没什么关系 # def eat(self): # print("%s is eating.." % self.name) # 则会报错 :TypeError: eat() missing 1 required positional argument: 'self'. # 这说明:静态方法:名义上归类管理,实际上静态方法里访问不了类或者实例中的任何属性
2.类方法:只能访问类变量,不能访问实例变量
# _*_ coding:utf-8 _*_ __author__ = "ZingP" class Dog(object): name = "xiaohu" def __init__(self, name): self.name = name @classmethod # 类方法 def eat(self): print("%s is eating.." % self.name) d = Dog("Baker") d.eat() # 运行结果:xiaohu is eating.. # 可以看出这里结果并不是Baker is eating..,说明调用的self.name是类变量,不是实例变量
3.属性方法:把一个方法变成类的私有属性
# _*_ coding:utf-8 _*_ __author__ = "ZingP" class Dog(object): def __init__(self, name): self.name = name @property def eat(self): print("%s is eating..." % self.name) d = Dog("baker") # d.eat() 这样会报错:TypeError: 'NoneType' object is not callable,这是eat已是静态属性,而非方法 d.eat # 这样才是正确的调用方法 # 运行结果:baker is eating... # @property 利用这个装饰器,把一个方法变成类的私有属性,调用就是:d.eat
3.1属性方法还可以这么用:
# _*_ coding:utf-8 _*_ __author__ = "ZingP" class Dog(object): def __init__(self, name): self.name = name self.__food = "bone" @property def eat(self): print("%s is eating %s..." % (self.name, self.__food)) @eat.setter def eat(self, food): print("set food:%s" % food) self.__food = food d = Dog("baker") d.eat # 运行结果:baker is eating bone... d.eat = "beef" # 运行结果:set food:beef d.eat # 运行结果:baker is eating beef...
3.2属性方法3:删除属性
# _*_ coding:utf-8 _*_ __author__ = "ZingP" class Dog(object): def __init__(self, name): self.name = name self.__food = None @property def eat(self): print("%s is eating %s..." % (self.name, self.__food)) @eat.setter def eat(self, food): print("set food:%s" % food) self.__food = food @eat.deleter def eat(self): del self.__food print("'__food'已删除。") d = Dog("baker") d.eat = "beef" d.eat # result: baker is eating None... del d.eat # '__food'已删除。 d.eat # result: AttributeError: 'Dog' object has no attribute '_Dog__food'
例: 把一个方法变成静态属性有什么卵用呢?既然想要静态变量,那直接定义成一个静态变量不就得了么?well, 以后你会需到很多场景是不能简单通过 定义 静态属性来实现的, 比如 ,你想知道一个航班当前的状态,是到达了、延迟了、取消了、还是已经飞走了, 想知道这种状态你必须经历以下几步:
1. 连接航空公司API查询
2. 对查询结果进行解析
3. 返回结果给你的用户
因此这个status属性的值是一系列动作后才得到的结果,所以你每次调用时,其实它都要经过一系列的动作才返回你结果,但这些动作过程不需要用户关心, 用户只需要调用这个属性就可以,明白 了么?
class Flight(object): def __init__(self,name): self.flight_name = name def checking_status(self): print("checking flight %s status " % self.flight_name) return 1 @property def flight_status(self): status = self.checking_status() if status == 0 : print("flight got canceled...") elif status == 1 : print("flight is arrived...") elif status == 2: print("flight has departured already...") else: print("cannot confirm the flight status...,please check later") f = Flight("CA980") f.flight_status
那现在我只能查询航班状态, 既然这个flight_status已经是个属性了, 那我能否给它赋值呢?试试吧
f = Flight("CA980") f.flight_status f.flight_status = 2
输出, 说不能更改这个属性,。。。。,怎么办怎么办???。。。
checking flight CA980 status flight is arrived... Traceback (most recent call last): File "/Users/jieli/PycharmProjects/python基础/自动化day7面向对象高级/属性方法.py", line 58, in <module> f.flight_status = 2 AttributeError: can't set attribute
当然可以改, 不过需要通过@proerty.setter装饰器再装饰一下,此时 你需要写一个新方法, 对这个flight_status进行更改。
class Flight(object): def __init__(self,name): self.flight_name = name def checking_status(self): print("checking flight %s status " % self.flight_name) return 1 @property def flight_status(self): status = self.checking_status() if status == 0 : print("flight got canceled...") elif status == 1 : print("flight is arrived...") elif status == 2: print("flight has departured already...") else: print("cannot confirm the flight status...,please check later") @flight_status.setter #修改 def flight_status(self,status): status_dic = { 0 : "canceled", 1 :"arrived", 2 : "departured" } print("\033[31;1mHas changed the flight status to \033[0m",status_dic.get(status) ) @flight_status.deleter #删除 def flight_status(self): print("status got removed...") f = Flight("CA980") f.flight_status f.flight_status = 2 #触发@flight_status.setter del f.flight_status #触发@flight_status.deleter
注意以上代码里还写了一个@flight_status.deleter, 是允许可以将这个属性删除 。
4.类的特殊成员方法:
1).__doc__ :表示类的描述信息
class Dog(object): """This is uesed in discribing info of the class.""" def __init__(self, name): self.name = name print(Dog.__doc__) # result: This is uesed to discribe info of the class. # __doc__ ,It is uesed to discribe info of the class.
2).__call__:
# _*_ coding:utf-8 _*_ __author__ = "ZingP" class Dog(object): def __init__(self, name): self.name = name @property def eat(self): print("%s is eating..." % self.name) def __call__(self, *args, **kwargs): print("This is call:", args, kwargs) d = Dog("baker") Dog("baker")() # 运行结果:This is call: () {} Dog("baker")(1, 2, 3, name="xiaohu") # 运行结果:This is call: (1, 2, 3) {'name': 'xiaohu'} # __call__函数可以在实例函数后面加(),传参数,直接执行。
3).__module__ 和 __class__
__module__ 表示当前操作的对象在那个模块
__class__ 表示当前操作的对象的类是什么
# _*_ coding:utf-8 _*_ __author__ = "ZingP" from __call__ import Dog d = Dog("Baker") print(d.__module__) # result: __call__ print(d.__class__) # result: <class '__call__.Dog'>
4).__dict__ 查看类或对象中的所有成员
# _*_ coding:utf-8 _*_ __author__ = "ZingP" class Dog(object): n = 3 def __init__(self, name): self.name = name def func(self): print("My name is %s..." % self.name) print(Dog.__dict__) # result: # {'__weakref__': <attribute '__weakref__' of 'Dog' objects>, '__dict__': <attribute '__dict__' of 'Dog' objects>, '__module__': '__main__', 'n': 3, # '__init__': <function Dog.__init__ at 0x01CBE228>, 'func': <function Dog.func at 0x01CBE1E0>, '__doc__': None}
5).__getitem__、__setitem__、__delitem__
用于索引操作,如字典。以上分别表示获取、设置、删除数据
# _*_ coding:utf-8 _*_ __author__ = "ZingP" class Foo(object): def __getitem__(self, key): print('__getitem__', key) def __setitem__(self, key, value): print('__setitem__', key, value) def __delitem__(self, key): print('__delitem__', key) obj = Foo() result = obj['k1'] # 自动触发执行 __getitem__ obj['k2'] = 'alex' # 自动触发执行 __setitem__ del obj['k1'] print(obj.__getitem__) # __getitem__ k1 # __setitem__ k2 alex # __delitem__ k1 # <bound method Foo.__getitem__ of <__main__.Foo object at 0x015CA3F0>>
6).__init__/__del__ 构造函数和析构函数见上一篇day6【面向对象】
7).__new__/__metaclass__见Alex博客,且这讲的是python2机制,与python3有差别
8).__str__ 如果一个类中定义了__str__方法,那么在打印 对象 时,默认输出该方法的返回值。
class Foo: def __str__(self): return 'zingp' obj = Foo() print obj # result:zingp
5.反射:通过字符串映射或修改程序运行时的状态、属性、方法, 有以下4个方法
# _*_ coding:utf-8 _*_ __author__ = "ZingP" class Dog(object): def __init__(self, name): self.name = name def eat(self): print("%s is eating..." % self.name) d = Dog("baker") def tell(self): print("my name is %s..." % self.name) choice = input(">>>:") if hasattr(d, choice): # hasattr(obj, 'name')检查是否含有成员 getattr(d, choice)() # getattr(obj, 'name')这里是返回类中字符串choice对应的方法的内存地址,加()调用 else: # setattr(d, choice, 22) # 为实例添加属性 setattr(d, choice, tell) # setattr(obj,'name',func)这里是输入的choice字符串 对应的方法为tell() func = getattr(d, choice) func(d) delattr(d,choice) # delattr(obj, 'name') 删除成员 # 比如 输入的choice是 "talk" ,相当于给实例d增加了方法: def talk(self): # tell(self) # 而 d.choice ---->d."talk" 所以不对,d.tell 则会报错说d这个对象没有tell属性,因为有talk属性,没有tell属性。 #
二、异常处理
1.一般异常
# _*_ coding:utf-8 _*_ __author__ = "ZingP" name = ["zing-p", "nancy", "baby"] data = {"name": "zing-p"} try: # name[4] data["key"] except IndexError as e: # 多个错误可写成:(IndexError, KeyError) print(e) except KeyError as e: print("没有这个key", e) except Exception as e: print("未知错误:", e) else: print("try 中没有错误,执行else。") finally: print("不管有没有错,都执行finally。") # result: # 没有这个key 'key' # 不管有没有错,都执行finally。
2.自定义异常:
# _*_ coding:utf-8 _*_ __author__ = "ZingP" class MyError(Exception): def __init__(self, msg): self.message = msg # def __str__(self): # return 'sdfsf' try: raise MyError('数据库连不上') except MyError as e: print(e) # result:数据库连不上
三.socket编程:
server端:
# _*_ coding:utf-8 _*_ __author__ = "ZingP" import socket server = socket.socket() # 声明 server.bind(("localhost", 9000)) # 绑定监听端口 server.listen() # 开始监听 conn, addr = server.accept() # conn就是客户端连过来,服务器为其生成的一个连接实例。 data = conn.recv(1024) # 接收数据 conn.send(data.upper()) # 返回数据 server.close()
client端
# _*_ coding:utf-8 _*_ __author__ = "ZingP" import socket client = socket.socket() # 声明 client.connect(("localhost", 9000)) # 连接 client.send(b"hello world!") # 发送请求 # client.send("我是zing-p".encode("utf-8")) data = client.recv(1024) # 接收数据 print("recv:", data) # 打印接收数据 client.close()
更多:http://www.cnblogs.com/wupeiqi/articles/5040823.html