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"]

Python学习笔记【第十一篇】:Python面向对象高级

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

Python学习笔记【第十一篇】:Python面向对象高级

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

Python学习笔记【第十一篇】:Python面向对象高级

 工厂模式案例:

 # -*- 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>
上一篇:Mysql系列二:Mysql 开发标准规范


下一篇:Windows下elasticsearch插入数据报错!