Python学习笔记【第十一篇】:Python面向对象高级
isinstance(obj,cls)和issubclass(sub,super)
class Person(object):
def __init__(self, name, age, sex, nationality):
self.name = name
self.age = age
self.sex = sex
self.nationality = nationality def say(self):
print("大家好我叫:%s 今年%d岁了,我是一名%s生来自%s。" % (self.name, self.age, self.sex, self.nationality)) def __getattr__(self, item):
print("当实例获取属性不存在的时候会执行__getattr__方法") def __getattribute__(self, item):
print("实例获取属性,不管实例dict属性字典里又没有都会执行__getattribute__方法") class Chinese(Person):
pass if __name__ == "__main__":
p1 = Person("里斯", 78, '男', "美国")
# p1 实例是否是Person类的一个实例
print(isinstance(p1, Person))
# issubclass(sub, super)检查sub类是否是 super 类的派生类
print(issubclass(Chinese, Person))
isinstance(obj,cls)检查是否obj是否是类 cls 的对象
issubclass(sub, super)检查sub类是否是 super 类的派生类
反射
python面向对象中的反射:通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射)
hasattr(obj,"属性"):# obj.属性是否存在
getattr(obj,"属性"):# 获取 obj.属性 如果不存在就报错
getattr(obj,"属性","默认值"):# 获取 obj.属性 如果不存在不会报错,并且返回默认的
setattr(obj,"属性"):# 设置属性
delattr(obj,"属性"):# 删除属性
# -*- coding: utf-8 -*- # 声明字符编码
# coding:utf-8 class Person(object):
name = "hah" def __init__(self, name, age, sex, nationality):
self.name = name
self.age = age
self._sex = sex
self.__nationality = nationality def say(self):
print("大家好我叫:%s 今年%d岁了,我是一名%s生来自%s" % (self.name, self.age, self._sex, self.__nationality)) class Chinese(Person):
pass if __name__ == "__main__":
print("\r\n ==============对象的反射============ \r\n")
p1 = Person("张三", 18, '男', "中国")
p1.say()
# 获取 p1 对象里name的值
print(getattr(p1, "name")) # 判断p1对象里又没有addr属性
print(hasattr(p1, "addr")) # 设置p1 对象addrs属性并且赋值
setattr(p1, "addrs", "四川达州")
print(getattr(p1, "addrs")) # 删除p1对象addrs属性
delattr(p1, "addrs")
print(hasattr(p1, "addrs")) print("\r\n ==============类的反射(类本质上也是对象)============ \r\n")
print(hasattr(Person, "addrs"))
print(getattr(Person, "name", "没有这个属性"))
setattr(Person, "addrs", "类地址")
print(getattr(Person, "addrs"))
delattr(Person, "name")
print(hasattr(Person, "name"))
importlib---动态导入模块
# -*- coding: utf-8 -*- # 声明字符编码
# coding:utf-8 from Python基础.myImport import chufa
import importlib if __name__ == "__main__":
# 第一种导入调用
# print(chufa(1000,50)) # 第二种:动态导入模块
# m1 = __import__("myImport")
# print(m1)
# # 调用模块里的方法
# print(m1.chufa(10,2)) # # 第三中:动态导入模块
# m2 = importlib.import_module("myImport")
# print(m2)
# print(m2.chufa(4,2))
m3 = importlib.import_module("modular.sendMsg")
print(m3)
print(m3.SendMsage())
__setattr__,__delattr__,__getattr__
__getattr__:不存在的时候出发
__setattr__:设置属性的值的时候出发
__delattr__:删除属性的时候出发
# -*- coding: utf-8 -*- # 声明字符编码
# coding:utf-8 """
__getattr__:不存在的时候出发
__setattr__:设置属性的值的时候出发
__delattr__:删除属性的时候出发 """ class Person(object):
def __init__(self, name, age, sex, nationality):
self.name = name
self.age = age
self.sex = sex
self.nationality = nationality def say(self):
print("大家好我叫:%s 今年%d岁了,我是一名%s生来自%s。" % (self.name, self.age, self.sex, self.nationality)) def __getattr__(self, item):
print("执行了__getattr__") def __setattr__(self, key, value):
print("执行了__setattr__")
# 实际上就是操作属性字典
self.__dict__[key] = value def __delattr__(self, item):
print("执行了__delattr__")
self.__dict__.pop(item) class Chinese(Person):
pass class American(Person):
pass class Korean(Person):
pass class Japanese(Person):
pass if __name__ == "__main__":
pass
# # 因为在类中重写了设置属性的方法,然而代码里并没有正在设置上,所以调用say会报错
# p1 = Person("张三",18,'男',"中国")
# p1.say() # 修改后在执行
p1 = Person("张三", 18, '男', "中国")
p1.say()
del p1.name
print(hasattr(p1, "name"))
__getattr__例子:
# -*- coding: utf-8 -*- # 声明字符编码
# coding:utf-8 import time class FileHelper(object):
def __init__(self, filepath, model="r", encoding='utf-8'):
self.file = open(filepath, mode=model, encoding=encoding) def __getattr__(self, item):
# item 是字符串类型
# 通过getattr()获取 self.file 中的方法
return getattr(self.file, item) def write(self, line):
# 在每次写入的内容前面加上时间
t = time.strftime("%Y-%m-%d %X")
self.file.write('%s %s' % (t, line + "\r\n")) if __name__ == "__main__":
f1 = FileHelper("../files/Log/logger.log", 'w', encoding='utf-8')
f1.write("锄禾日当午")
f1.write("汗滴禾下土")
f1.write("谁知盘中餐")
f1.write("粒粒皆辛苦") f1 = FileHelper("../files/Log/logger.log", 'r', encoding='utf-8')
# f1.read() 首先在f1实例中的__dict__数据字典中去找read方法,如果没有就去FileHelper类中的__dict__数据字典中找,如果还是没有
# 就报错,如果在FileHelper中重写的__getattr__方法,就执行该方法。所以在该方法中通过self.file属性中去找,self.file就是系统的open对象。
content = f1.read()
print(content)
__setitem__,__getitem,__delitem__
class Chinese(Person): def __getitem__(self, item):
print("执行了__getitem__") def __setitem__(self, key, value):
print("执行了__setitem__") def __delitem__(self, key):
print("执行了__delitem__")
c1 = Chinese("李四",14,"女","中国")
c1["addrs"] = "四川成都"
c1['addrs']
del c1["addrs"]
__getattribute__
# -*- coding: utf-8 -*- # 声明字符编码
# coding:utf-8 class Person(object):
def __init__(self, name, age, sex, nationality):
self.name = name
self.age = age
self.sex = sex
self.nationality = nationality def say(self):
print("大家好我叫:%s 今年%d岁了,我是一名%s生来自%s。" % (self.name, self.age, self.sex, self.nationality)) def __getattr__(self, item):
print("当实例获取属性不存在的时候会执行__getattr__方法") def __getattribute__(self, item):
print("实例获取属性,不管实例dict属性字典里又没有都会执行__getattribute__方法") if __name__ == "__main__":
p1 = Person("里斯", 78, '男', "美国")
# p1 实例是否是Person类的一个实例
print(isinstance(p1, Person))
# issubclass(sub, super)检查sub类是否是 super 类的派生类
print(issubclass(Chinese, Person)) # getattribute方法
# addrs不存在与p1的dict属性字典里,所以会执行getattr方法
p1.addrs
p1.name
"""
当实例中同时具有__getattr__和__getattribute__方法时候,都只会执行__getattribute__方法,如果__getattribute__方法里有
抛出AttributeError异常,就会出发 __getattr__方法。 """
总结
obj点的方式操作属性时候出发
__getattr__:不存在的时候出发
__setattr__:设置属性的值的时候出发
__delattr__:删除属性的时候出发 obj['属性']的的方式操作属性的时候出发
__getitem__:不存在的时候出发
__setitem__:设置属性的值的时候出发
__delitem__:删除属性的时候出发
def __get__():
pass
def __set__():
pass
def __del__():
pass 描述的就是一个新式类,这个类至少实现上述三个方法中的一个
改变对象的字符串显示__str__,__repr__
# -*- coding: utf-8 -*- # 声明字符编码
# coding:utf-8 # 改变对象的字符串显示__str__,__repr__ class Person(object):
def __init__(self, name, age, sex, nationality):
self.name = name
self.age = age
self.sex = sex
self.nationality = nationality def say(self):
print("大家好我叫:%s 今年%d岁了,我是一名%s生来自%s。" % (self.name, self.age, self.sex, self.nationality)) def __str__(self):
return '重写str方法,默认就返回我啦!!!' def __repr__(self):
return '通过解释器执行后返回的' if __name__ == "__main__":
# 实例中没有__str__函数,打印实例 地址,加了之后,打印重写后返回的内容。
p1 = Person("小村伊朗", 78, '妖', '小岛')
print(p1)
__next__和__iter__实现迭代器协议
高效的求斐波拉契数列方法
# -*- coding: utf-8 -*- # 声明字符编码
# coding:utf-8 class FeiBoLa(object):
def __init__(self):
self.__a = 1
self.__b = 1 def __iter__(self):
return self def __next__(self):
self.__a, self.__b = self.__b, self.__a + self.__b
return self.__a if __name__ == "__main__":
f = FeiBoLa()
print(f.__next__())
print(f.__next__())
print(f.__next__())
print(f.__next__())
print(f.__next__())
__enter__和__exit__组成with语法
with MyOpen('a.txt') as f:
print(f)
print('执行代码块')
# -*- coding: utf-8 -*- # 声明字符编码
# coding:utf-8
""" 案例:
with MyOpen('a.txt','r',encoding='utf-8') as f:
pass __enter__(): MyOpen('a.txt','r',encoding='utf-8') 会触发 MyOpen类中的__enter__方法
__exit__():执行完代码块中的代码后出发 __exit__方法。 """ class MyOpen(object):
def __init__(self, path, model='r', encoding='utf-8'):
self.path = path
self.model = model
self.encoding = encoding def __enter__(self):
print('执行了enter方法.....') def __exit__(self, exc_type, exc_val, exc_tb):
# 如果发生异常 对应三个值的说明
# exc_type:异常类, exc_val:异常值, exc_tb:异常追踪信息
print('执行了exit方法......')
print(exc_type)
print(exc_val)
print(exc_tb)
return False if __name__ == "__main__":
with MyOpen('a.txt') as f:
print(f)
print('执行代码块')
案例:
描述符类装饰器给类动态添加属性
# -*- coding: utf-8 -*- # 声明字符编码
# coding:utf-8 # 类属性描述
class AttrDesc: def __init__(self, attr_name, attr_type):
self.attr_name = attr_name
self.attr_type = attr_type def __get__(self, instance, owner):
return instance.__dict__[self.attr_name] def __set__(self, instance, value):
if not isinstance(value, self.attr_type):
raise TypeError("%s值的类型不是:%s" % (self.attr_name, self.attr_type))
instance.__dict__[self.attr_name] = value def __delete__(self, instance):
return instance.__dict__.pop(self.attr_name) # 限制类属性类型装饰器
def add_attr(**kwargs):
def add(obj):
for key, val in kwargs.items():
setattr(obj, key, AttrDesc(key, val)) return obj return add @add_attr(height=float, weigt=float, name=str)
class Person(object):
def __init__(self, name, age, sex, nationality):
self.name = name
self.age = age
self.sex = sex
self.nationality = nationality def say(self):
print("大家好我叫:%s 今年%d岁了,我是一名%s生来自%s。" % (self.name, self.age, self.sex, self.nationality)) if __name__ == "__main__":
p1 = Person('小明', 12, '男', '中国')
p1.height = 2.19
print(Person.__dict__)
案例:自定义property
可以让一个方法 看起来像一个属性,使用的时候对象点出来即可
# -*- coding: utf-8 -*- # 声明字符编码
# coding:utf-8 class LazyPropery:
def __init__(self, func):
self.func = func def __get__(self, instance, owner):
print(instance)
print(owner)
if instance is None:
return self
return self.func(instance) class Person(object):
def __init__(self, name, age, sex, nationality):
self.name = name
self.age = age
self.sex = sex
self.nationality = nationality # 标记上@property 变为静态属性,这样就可以通过实例名点方法名调用。
@property
def say(self):
print("大家好我叫:%s 今年%d岁了,我是一名%s生来自%s。" % (self.name, self.age, self.sex, self.nationality)) class Chinese(Person): @LazyPropery
def run(self):
print('run')
return '我是%s' % self.name if __name__ == "__main__":
print("\r\n======系统内置property=====\r\n")
p1 = Person('王二小', 12, '女', '中国')
p1.say
print("\r\n======自定义的property=====\r\n")
c1 = Chinese('王二', 15, '女', '中国')
print(c1.run)
工厂模式案例:
# -*- coding: utf-8 -*- # 声明字符编码
# coding:utf-8
'''
在父类中定义,在子类中实现 ========工厂模式
''' # 店铺类
class Store(object):
def select_car(self):
pass def Order(self, car_type):
return self.select_car(car_type) # 宝马4S店
class BMStore(Store):
def select_car(self, car_type):
return BMFactory().select_car_by_type(car_type) # 桑塔纳4S店
class STNStore(Store):
def select_car(self, car_type):
return STNFactory().select_car_by_type(car_type) # 雪佛兰4S店
class XFLStore(Store):
def select_car(self, car_type):
return XFLFactory().select_car_by_type(car_type) # 宝马工厂
class BMFactory(object):
def select_car_by_type(self, car_type):
if car_type == "宝马X": return BaoMaX()
if car_type == "宝马XX": return BaoMaXX()
if car_type == "宝马XXX": return BaoMaXXX() # 桑塔纳工厂
class STNFactory(object):
def select_car_by_type(self, car_type):
if car_type == "桑塔纳Q": return SangTaNaQ()
if car_type == "桑塔纳QQ": return SangTaNaQQ() # 雪佛兰工厂
class XFLFactory(object):
def select_car_by_type(self, car_type):
if car_type == "雪佛兰T": return XueFuLanT()
if car_type == "雪佛兰TT": return XueFuLanTT() # 整个车类
class Car(object):
def move(self):
print("车在移动......") def music(self):
print("车里再放音乐....") def stop(self):
print("车停下了.......") # 宝马车类
class BaoMa(Car):
pass class BaoMaX(BaoMa):
pass class BaoMaXX(BaoMa):
pass class BaoMaXXX(BaoMa):
pass # 桑塔纳车类
class SangTaNa(Car):
pass class SangTaNaQ(SangTaNa):
pass class SangTaNaQQ(SangTaNa):
pass # 雪佛兰车类
class XueFuLan(Car):
pass class XueFuLanT(XueFuLan):
pass class XueFuLanTT(XueFuLan):
pass stor = BMStore()
s = stor.Order("宝马XX")
s.move()
s.music()
s.stop()
简单工厂模式案例:
# -*- coding: utf-8 -*- # 声明字符编码
# coding:utf-8 #<region 简单工厂模式> # 店铺类
class CarStore(object):
def __init__(self):
self.factory = Factory()
def Order(self,car_type):
return self.factory.select_car_by_type(car_type) # # 店铺类
# class CarStore(object):
# def Order(self,car_type):
# return select_car_by_type(car_type) class Factory(object):
def select_car_by_type(self,car_type):
if car_type =="宝马":return BaoMa()
if car_type == "桑塔纳":return SangTaNa()
if car_type == "雪佛兰":return XueFuLan() # # 函数(达到了解耦性)
# def select_car_by_type(car_type):
# if car_type =="宝马":return BaoMa()
# if car_type == "桑塔纳":return SangTaNa()
# if car_type == "雪佛兰":return XueFuLan() # 整个车类
class Car(object):
def move(self):
print("车在移动......")
def music(self):
print("车里再放音乐....")
def stop(self):
print("车停下了.......") # 宝马车类
class BaoMa(Car):
pass
# 桑塔纳车类
class SangTaNa(Car):
pass
# 雪佛兰车类
class XueFuLan(Car):
pass stor = CarStore()
s = stor.Order("宝马")
s.move()
s.music()
s.stop() #<endregion>
Python学习笔记【第十一篇】:Python面向对象高级的更多相关文章
- Python 学习笔记(十一)Python语句(三)
While 循环语句 用于循环执行程序,即在某条件下,循环执行某段程序,以处理需要重复处理的相同任务. 语法: while 判断条件: 执行语句…… 执行语句可以是单个语句或语句块.判断条件可以是任何 ...
- Python 学习笔记(十一)Python语句(二)
For 循环语句 基础知识 for循环可以遍历任何序列的项目,如一个列表或者一个字符串. 语法: for 循环规则: do sth >>> for i in "python ...
- Python 学习笔记(十一)Python语句(一)
运算符和条件语句 算术运算符 运算符 描述 实例 + 加 - 两个对象相加 a + b 输出结果 30 - 减 - 得到负数或是一个数减去另一个数 a - b 输出结果 -10 * 乘 - 两个数相乘 ...
- Python学习笔记(十一)
Python学习笔记(十一): 生成器,迭代器回顾 模块 作业-计算器 1. 生成器,迭代器回顾 1. 列表生成式:[x for x in range(10)] 2. 生成器 (generator o ...
- Python学习笔记之基础篇(-)python介绍与安装
Python学习笔记之基础篇(-)初识python Python的理念:崇尚优美.清晰.简单,是一个优秀并广泛使用的语言. python的历史: 1989年,为了打发圣诞节假期,作者Guido开始写P ...
- openresty 学习笔记番外篇:python的一些扩展库
openresty 学习笔记番外篇:python的一些扩展库 要写一个可以使用的python程序还需要比如日志输出,读取配置文件,作为守护进程运行等 读取配置文件 使用自带的ConfigParser模 ...
- openresty 学习笔记番外篇:python访问RabbitMQ消息队列
openresty 学习笔记番外篇:python访问RabbitMQ消息队列 python使用pika扩展库操作RabbitMQ的流程梳理. 客户端连接到消息队列服务器,打开一个channel. 客户 ...
- Python 学习笔记(基础篇)
背景:今年开始搞 Data science ,学了 python 小半年,但一直没时间整理整理.这篇文章很基础,就是根据廖雪峰的 python 教程 整理了一下基础知识,再加上自己的一些拓展,方便自己 ...
- Python学习笔记——基础语法篇
一.Python初识(IDE环境及基本语法,Spyder快捷方式) Python是一种解释型.面向对象.动态数据类型的高级程序设计语言,没有编译过程,可移植,可嵌入,可扩展. IDE 1.检查Pyth ...
- python学习笔记:安装boost python库以及使用boost.python库封装
学习是一个累积的过程.在这个过程中,我们不仅要学习新的知识,还需要将以前学到的知识进行回顾总结. 前面讲述了Python使用ctypes直接调用动态库和使用Python的C语言API封装C函数, C+ ...
随机推荐
- HDU2035
#include <bits/stdc++.h> using namespace std; int fastpow(int a,int b,int k) { ; while(b) { ) ...
- yii2.0 邮件发送如何配置
邮件发送配置: 打开配置文件将下面代码添加到 components => [...]中(例:高级版默认配置在/common/config/main-local.php) 'mai ...
- iptables命令提取总结,包含扩展模块<取自朱双印博客>
以下内容只是一些命令相关的,以朱双印博客中的iptables的教程提取出来的.纯粹只是命令的总结,如果需要看理论的知识,建议去看朱老师的博客,目前还没有看到写得比这个好的了. <http://w ...
- STS中db.properties配置文件
db.name=root db.password=root db.url=jdbc:mysql://localhost:3306/day13?useUnicode=true&character ...
- Vue+Webpack构建去哪儿APP_一.开发前准备
一.开发前准备 1.node环境搭建 去node.js官网下载长期支持版本的node,采用全局安装,安装方式自行百度 网址:https://nodejs.org/zh-cn/ 安装后在cmd命令行运行 ...
- C++标准库第二版笔记 3 和异常的理解 1
C++标准库第二版笔记 3 和异常的理解 1 差错和异常(error and exception)的处理 标准异常类(exception class) 定义于 分为: 1.语言本身支持的异常 2.标准 ...
- homework1-201521410029
姓名:孙浩学号: 201521410029指导教师:高见 实验日期:2018年8月9日 1. 虚拟机安装与调试 安装好xp和kali虚拟机之后,查看这三者(包括主机)的i ...
- Java实现AES加密,异常java.security.InvalidKeyException: Illegal key size 的解决
Java实现AES加密,抛出异常如下:java.security.InvalidKeyException: Illegal key size 代码参考 http://my.oschina.net/Ja ...
- IOS KVO没有在delloc中移除导致奔溃
1.背景 为了监听tableview的移动 [_tableView addObserver:self forKeyPath:@"contentOffset" options:NSK ...
- ES6使用fetch请求数据
ie是完全不支持fetch的. fetch(url,{method:"get/post"}).then(res=>{ }) 如果请求返回的status是200,body是 ...