Python【第七篇】面向对象进阶
大纲
一、面向对象高级语法
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
Python【第七篇】面向对象进阶的更多相关文章
- python(24)- 面向对象进阶
面向对象基础知识: 1.面向对象是一种编程方式,此编程方式的实现是基于对类和对象的使用: 2.类是一个模板,模板中包装了多个‘函数’供使用(可以将多函数中公用的变量封装到对象中): 3.对象,根据模板 ...
- Python之路(第二十六篇) 面向对象进阶:内置方法
一.__getattribute__ object.__getattribute__(self, name) 无条件被调用,通过实例访问属性.如果class中定义了__getattr__(),则__g ...
- Python之路(第二十九篇) 面向对象进阶:内置方法补充、异常处理
一.__new__方法 __init__()是初始化方法,__new__()方法是构造方法,创建一个新的对象 实例化对象的时候,调用__init__()初始化之前,先调用了__new__()方法 __ ...
- Python之路(第二十八篇) 面向对象进阶:类的装饰器、元类
一.类的装饰器 类作为一个对象,也可以被装饰. 例子 def wrap(obj): print("装饰器-----") obj.x = 1 obj.y = 3 obj.z = 5 ...
- Python之路(第二十七篇) 面向对象进阶:内置方法、描述符
一.__call__ 对象后面加括号,触发执行类下面的__call__方法. 创建对象时,对象 = 类名() :而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()( ...
- python基础-9.1 面向对象进阶 super 类对象成员 类属性 私有属性 查找源码类对象步骤 类特殊成员 isinstance issubclass 异常处理
上一篇文章介绍了面向对象基本知识: 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个“函数”供使用(可以讲多函数中公用的变量封装到对象中) 对象 ...
- python之旅:面向对象进阶
一 isinstance(obj,cls)和issubclass(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls 的对象 class Foo(object) ...
- python全栈开发-面向对象-进阶2
python_day_19 今日主要内容: 1.抽象类,接口类 2.多态 3.封装 1.抽象类,接口类 python 没有接口这个概念接口类,抽象类: 制定一个规范. 举个栗子:你的项目经理提一个需求 ...
- Python第七章-面向对象
面向对象编程基础 一.面向对象概念 1.1 什么是面向过程 就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了. 生活中的的例子举例. 1.2 ...
- Python第七章-面向对象高级
面向对象高级 一. 特性 特性是指的property. property这个词的翻译一直都有问题, 很多人把它翻译为属性, 其实是不恰当和不准确的. 在这里翻译成特性是为了和属性区别开来. 属性是指的 ...
随机推荐
- java对Ldap操作3
")); }}
- FIREDAC TFDCONNECTION连接MYSQL数据库
FIREDAC TFDCONNECTION连接MYSQL数据库 procedure TfrmDB.ConnectDB;begin FDMoniFlatFileClientLink1.FileName ...
- highcharts动态获取数据生成图表问题
动态获取数据说白点就是从后台传值到前台,前台把这些值赋值给x轴与y轴(这里指的是你X轴与Y轴都是变化的数据,如果你的X轴是固定的,像时间等等的那就另说). 柱状图的动态传值: //获取后台数据 va ...
- 【转】jQuery列表拖动排列-jquery list dragsort插件参数和使用方法
转自:http://www.itokit.com/2014/0820/75058.html 我们在编辑页面元素排序的时候,我推荐使用jquery插件:dragsort. dragsort官网地址:ht ...
- 推荐一个markdown编辑器-MarkdownPad
MarkdownPad - The Markdown Editor for Windows是一个很不错的windows下的markdown的编辑器,对于我这种总是记不住各种语法的人来说,非常方便. 免 ...
- javascript数组基本方法
一.数组方法 1)concat 该方法用于连接两个或多个数组,返回连接成的新数组的副本,不会改变现有数组 [1,2,3].concat(5,6);//返回[1,2,3,5,6] 2)join 用于把数 ...
- python google play
#!/usr/env python #-*- coding: utf-8 -*- import urllib import urllib2 import random import requests ...
- tcpdump抓包以及port查看的一些操作
1.tcpdump. nginx开启后会占用80端口,此时运行命令:tcpdump tcp port 80 结果例如以下: [syswj@host ~]$ sudo tcpdump tcp port ...
- linux块设备IO栈浅析
http://www.sysnote.org/2015/08/06/linux-io-stack/
- AndroidStudio工程文件导入Jar包和So第三方库
AndroidStudio 导入Jar包和第三方So库 在android开发中,需要导入许多第三方的jar包和so库来支持,包括像许多第三方的支持平台--友盟,环信.融云.极光推送.微博.腾讯等第三方 ...