欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-03-25 22:04:57
isinstance(obj,cls)和issubclass(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls 的对象 issubclass(sub, super)检查sub类是否是 super 类的派生类 反射 python面向对象中的反射:通过字符串的形 ......

 isinstance(obj,cls)和issubclass(sub,super)

 1 class Person(object):
 2     def __init__(self, name, age, sex, nationality):
 3         self.name = name
 4         self.age = age
 5         self.sex = sex
 6         self.nationality = nationality
 7 
 8     def say(self):
 9         print("大家好我叫:%s 今年%d岁了,我是一名%s生来自%s。" % (self.name, self.age, self.sex, self.nationality))
10 
11     def __getattr__(self, item):
12         print("当实例获取属性不存在的时候会执行__getattr__方法")
13 
14     def __getattribute__(self, item):
15         print("实例获取属性,不管实例dict属性字典里又没有都会执行__getattribute__方法")
16 
17 
18 class Chinese(Person):
19         pass
20 
21     
22 if __name__ == "__main__":
23     p1 = Person("里斯", 78, '男', "美国")
24     # p1 实例是否是Person类的一个实例
25     print(isinstance(p1, Person))
26     # issubclass(sub, super)检查sub类是否是 super 类的派生类
27     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,"属性"):# 删除属性

 1 # -*- coding: utf-8 -*-
 2 
 3 # 声明字符编码
 4 # coding:utf-8
 5  
 6 
 7 class Person(object):
 8     name = "hah"
 9 
10     def __init__(self, name, age, sex, nationality):
11         self.name = name
12         self.age = age
13         self._sex = sex
14         self.__nationality = nationality
15 
16     def say(self):
17         print("大家好我叫:%s 今年%d岁了,我是一名%s生来自%s" % (self.name, self.age, self._sex, self.__nationality))
18 
19 
20 class Chinese(Person):
21     pass
22 
23 
24 if __name__ == "__main__":
25     print("\r\n ==============对象的反射============ \r\n")
26     p1 = Person("张三", 18, '男', "中国")
27     p1.say()
28     # 获取 p1 对象里name的值
29     print(getattr(p1, "name"))
30 
31     # 判断p1对象里又没有addr属性
32     print(hasattr(p1, "addr"))
33 
34     # 设置p1 对象addrs属性并且赋值
35     setattr(p1, "addrs", "四川达州")
36     print(getattr(p1, "addrs"))
37 
38     # 删除p1对象addrs属性
39     delattr(p1, "addrs")
40     print(hasattr(p1, "addrs"))
41 
42     print("\r\n ==============类的反射(类本质上也是对象)============ \r\n")
43     print(hasattr(Person, "addrs"))
44     print(getattr(Person, "name", "没有这个属性"))
45     setattr(Person, "addrs", "类地址")
46     print(getattr(Person, "addrs"))
47     delattr(Person, "name")
48     print(hasattr(Person, "name"))

importlib---动态导入模块
 1 # -*- coding: utf-8 -*-
 2 
 3 # 声明字符编码
 4 # coding:utf-8
 5 
 6 from Python基础.myImport import chufa
 7 import importlib
 8 
 9 if __name__ == "__main__":
10     # 第一种导入调用
11     # print(chufa(1000,50))
12 
13     # 第二种:动态导入模块
14     # m1 = __import__("myImport")
15     # print(m1)
16     # # 调用模块里的方法
17     # print(m1.chufa(10,2))
18 
19     # # 第三中:动态导入模块
20     # m2 = importlib.import_module("myImport")
21     # print(m2)
22     # print(m2.chufa(4,2))
23     m3 = importlib.import_module("modular.sendMsg")
24     print(m3)
25     print(m3.SendMsage())

__setattr__,__delattr__,__getattr__

__getattr__:不存在的时候出发
__setattr__:设置属性的值的时候出发
__delattr__:删除属性的时候出发
 1 # -*- coding: utf-8 -*-
 2 
 3 # 声明字符编码
 4 # coding:utf-8
 5 
 6 """
 7 __getattr__:不存在的时候出发
 8 __setattr__:设置属性的值的时候出发
 9 __delattr__:删除属性的时候出发
10 
11 """
12 
13 
14 class Person(object):
15     def __init__(self, name, age, sex, nationality):
16         self.name = name
17         self.age = age
18         self.sex = sex
19         self.nationality = nationality
20 
21     def say(self):
22         print("大家好我叫:%s 今年%d岁了,我是一名%s生来自%s。" % (self.name, self.age, self.sex, self.nationality))
23 
24     def __getattr__(self, item):
25         print("执行了__getattr__")
26 
27     def __setattr__(self, key, value):
28         print("执行了__setattr__")
29         # 实际上就是操作属性字典
30         self.__dict__[key] = value
31 
32     def __delattr__(self, item):
33         print("执行了__delattr__")
34         self.__dict__.pop(item)
35 
36 
37 class Chinese(Person):
38     pass
39 
40 
41 class American(Person):
42     pass
43 
44 
45 class Korean(Person):
46     pass
47 
48 
49 class Japanese(Person):
50     pass
51 
52 
53 if __name__ == "__main__":
54     pass
55     # # 因为在类中重写了设置属性的方法,然而代码里并没有正在设置上,所以调用say会报错
56     # p1 = Person("张三",18,'男',"中国")
57     # p1.say()
58 
59     # 修改后在执行
60     p1 = Person("张三", 18, '男', "中国")
61     p1.say()
62     del p1.name
63     print(hasattr(p1, "name")) 

__getattr__例子:

 1  # -*- coding: utf-8 -*-
 2  
 3  # 声明字符编码
 4  # coding:utf-8
 5  
 6  import time
 7  
 8  
 9  class FileHelper(object):
10      def __init__(self, filepath, model="r", encoding='utf-8'):
11          self.file = open(filepath, mode=model, encoding=encoding)
12  
13      def __getattr__(self, item):
14          # item 是字符串类型
15          # 通过getattr()获取 self.file 中的方法
16          return getattr(self.file, item)
17  
18      def write(self, line):
19          # 在每次写入的内容前面加上时间
20          t = time.strftime("%Y-%m-%d %X")
21          self.file.write('%s %s' % (t, line + "\r\n"))
22  
23  
24  if __name__ == "__main__":
25      f1 = FileHelper("../files/Log/logger.log", 'w', encoding='utf-8')
26      f1.write("锄禾日当午")
27      f1.write("汗滴禾下土")
28      f1.write("谁知盘中餐")
29      f1.write("粒粒皆辛苦")
30  
31      f1 = FileHelper("../files/Log/logger.log", 'r', encoding='utf-8')
32      # f1.read() 首先在f1实例中的__dict__数据字典中去找read方法,如果没有就去FileHelper类中的__dict__数据字典中找,如果还是没有
33      # 就报错,如果在FileHelper中重写的__getattr__方法,就执行该方法。所以在该方法中通过self.file属性中去找,self.file就是系统的open对象。
34      content = f1.read()
35      print(content)

 

__setitem__,__getitem,__delitem__ 

 1 class Chinese(Person):
 2 
 3     def __getitem__(self, item):
 4         print("执行了__getitem__")
 5 
 6     def __setitem__(self, key, value):
 7         print("执行了__setitem__")
 8 
 9     def __delitem__(self, key):
10         print("执行了__delitem__")
11     c1 = Chinese("李四",14,"女","中国")
12     c1["addrs"] = "四川成都"
13     c1['addrs']
14     del c1["addrs"]

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

 

__getattribute__

 1 # -*- coding: utf-8 -*-
 2 
 3 # 声明字符编码
 4 # coding:utf-8
 5  
 6 class Person(object):
 7     def __init__(self, name, age, sex, nationality):
 8         self.name = name
 9         self.age = age
10         self.sex = sex
11         self.nationality = nationality
12 
13     def say(self):
14         print("大家好我叫:%s 今年%d岁了,我是一名%s生来自%s。" % (self.name, self.age, self.sex, self.nationality))
15 
16     def __getattr__(self, item):
17         print("当实例获取属性不存在的时候会执行__getattr__方法")
18 
19     def __getattribute__(self, item):
20         print("实例获取属性,不管实例dict属性字典里又没有都会执行__getattribute__方法")
21 
22 
23 
24 if __name__ == "__main__":
25     p1 = Person("里斯", 78, '男', "美国")
26     # p1 实例是否是Person类的一个实例
27     print(isinstance(p1, Person))
28     # issubclass(sub, super)检查sub类是否是 super 类的派生类
29     print(issubclass(Chinese, Person))
30 
31     # getattribute方法
32     # addrs不存在与p1的dict属性字典里,所以会执行getattr方法
33     p1.addrs
34     p1.name
35     """ 
36     当实例中同时具有__getattr__和__getattribute__方法时候,都只会执行__getattribute__方法,如果__getattribute__方法里有
37     抛出AttributeError异常,就会出发 __getattr__方法。
38      
39     """

总结

  obj点的方式操作属性时候出发
  __getattr__:不存在的时候出发
  __setattr__:设置属性的值的时候出发
  __delattr__:删除属性的时候出发

  obj['属性']的的方式操作属性的时候出发
  __getitem__:不存在的时候出发
  __setitem__:设置属性的值的时候出发
  __delitem__:删除属性的时候出发
  
  def __get__():
   pass
  def __set__():
  pass
  def __del__():
   pass

  描述的就是一个新式类,这个类至少实现上述三个方法中的一个
改变对象的字符串显示__str__,__repr__
 1 # -*- coding: utf-8 -*-
 2 
 3 # 声明字符编码
 4 # coding:utf-8
 5 
 6 # 改变对象的字符串显示__str__,__repr__
 7 
 8 class Person(object):
 9     def __init__(self, name, age, sex, nationality):
10         self.name = name
11         self.age = age
12         self.sex = sex
13         self.nationality = nationality
14 
15     def say(self):
16         print("大家好我叫:%s 今年%d岁了,我是一名%s生来自%s。" % (self.name, self.age, self.sex, self.nationality))
17 
18     def __str__(self):
19         return '重写str方法,默认就返回我啦!!!'
20 
21     def __repr__(self):
22         return '通过解释器执行后返回的'
23 
24 
25 if __name__ == "__main__":
26     # 实例中没有__str__函数,打印实例 地址,加了之后,打印重写后返回的内容。
27     p1 = Person("小村伊朗", 78, '妖', '小岛')
28     print(p1)

__next__和__iter__实现迭代器协议

 高效的求斐波拉契数列方法

 1 # -*- coding: utf-8 -*-
 2 
 3 # 声明字符编码
 4 # coding:utf-8
 5 
 6 class FeiBoLa(object):
 7     def __init__(self):
 8         self.__a = 1
 9         self.__b = 1
10 
11     def __iter__(self):
12         return self
13 
14     def __next__(self):
15         self.__a, self.__b = self.__b, self.__a + self.__b
16         return self.__a
17 
18 
19 if __name__ == "__main__":
20     f = FeiBoLa()
21     print(f.__next__())
22     print(f.__next__())
23     print(f.__next__())
24     print(f.__next__())
25     print(f.__next__())

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

__enter__和__exit__组成with语法

with MyOpen('a.txt') as f:
         print(f)
         print('执行代码块')
 1 # -*- coding: utf-8 -*-
 2 
 3 # 声明字符编码
 4 # coding:utf-8
 5 """
 6 
 7 
 8 案例:
 9 with MyOpen('a.txt','r',encoding='utf-8') as f:
10     pass
11 
12 
13 __enter__(): MyOpen('a.txt','r',encoding='utf-8') 会触发 MyOpen类中的__enter__方法
14 __exit__():执行完代码块中的代码后出发 __exit__方法。
15 
16 """
17 
18 
19 class MyOpen(object):
20     def __init__(self, path, model='r', encoding='utf-8'):
21         self.path = path
22         self.model = model
23         self.encoding = encoding
24 
25     def __enter__(self):
26         print('执行了enter方法.....')
27 
28     def __exit__(self, exc_type, exc_val, exc_tb):
29         # 如果发生异常 对应三个值的说明
30         # exc_type:异常类, exc_val:异常值, exc_tb:异常追踪信息
31         print('执行了exit方法......')
32         print(exc_type)
33         print(exc_val)
34         print(exc_tb)
35         return False
36 
37 
38 if __name__ == "__main__":
39     with MyOpen('a.txt') as f:
40         print(f)
41         print('执行代码块')

案例:

  描述符类装饰器给类动态添加属性
 1 # -*- coding: utf-8 -*-
 2 
 3 # 声明字符编码
 4 # coding:utf-8
 5 
 6 # 类属性描述
 7 class AttrDesc:
 8 
 9     def __init__(self, attr_name, attr_type):
10         self.attr_name = attr_name
11         self.attr_type = attr_type
12 
13     def __get__(self, instance, owner):
14         return instance.__dict__[self.attr_name]
15 
16     def __set__(self, instance, value):
17         if not isinstance(value, self.attr_type):
18             raise TypeError("%s值的类型不是:%s" % (self.attr_name, self.attr_type))
19         instance.__dict__[self.attr_name] = value
20 
21     def __delete__(self, instance):
22         return instance.__dict__.pop(self.attr_name)
23 
24 
25 # 限制类属性类型装饰器
26 def add_attr(**kwargs):
27     def add(obj):
28         for key, val in kwargs.items():
29             setattr(obj, key, AttrDesc(key, val))
30 
31         return obj
32 
33     return add
34 
35 
36 @add_attr(height=float, weigt=float, name=str)
37 class Person(object):
38     def __init__(self, name, age, sex, nationality):
39         self.name = name
40         self.age = age
41         self.sex = sex
42         self.nationality = nationality
43 
44     def say(self):
45         print("大家好我叫:%s 今年%d岁了,我是一名%s生来自%s。" % (self.name, self.age, self.sex, self.nationality))
46 
47 
48 if __name__ == "__main__":
49     p1 = Person('小明', 12, '男', '中国')
50     p1.height = 2.19
51     print(Person.__dict__)

 

 案例:自定义property

       可以让一个方法 看起来像一个属性,使用的时候对象点出来即可

 1 # -*- coding: utf-8 -*-
 2 
 3 # 声明字符编码
 4 # coding:utf-8
 5 
 6 class LazyPropery:
 7     def __init__(self, func):
 8         self.func = func
 9 
10     def __get__(self, instance, owner):
11         print(instance)
12         print(owner)
13         if instance is None:
14             return self
15         return self.func(instance)
16 
17 
18 class Person(object):
19     def __init__(self, name, age, sex, nationality):
20         self.name = name
21         self.age = age
22         self.sex = sex
23         self.nationality = nationality
24 
25     # 标记上@property 变为静态属性,这样就可以通过实例名点方法名调用。
26     @property
27     def say(self):
28         print("大家好我叫:%s 今年%d岁了,我是一名%s生来自%s。" % (self.name, self.age, self.sex, self.nationality))
29 
30 
31 class Chinese(Person):
32 
33     @LazyPropery
34     def run(self):
35         print('run')
36         return '我是%s' % self.name
37 
38 
39 if __name__ == "__main__":
40     print("\r\n======系统内置property=====\r\n")
41     p1 = Person('王二小', 12, '女', '中国')
42     p1.say
43     print("\r\n======自定义的property=====\r\n")
44     c1 = Chinese('王二', 15, '女', '中国')
45     print(c1.run)

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

 

 工厂模式案例:

  1 # -*- coding: utf-8 -*-
  2 
  3 # 声明字符编码
  4 # coding:utf-8
  5 '''
  6 在父类中定义,在子类中实现 ========工厂模式
  7 '''
  8 
  9 
 10 # 店铺类
 11 class Store(object):
 12     def select_car(self):
 13         pass
 14 
 15     def Order(self, car_type):
 16         return self.select_car(car_type)
 17 
 18 
 19 # 宝马4S店
 20 class BMStore(Store):
 21     def select_car(self, car_type):
 22         return BMFactory().select_car_by_type(car_type)
 23 
 24 
 25 # 桑塔纳4S店
 26 class STNStore(Store):
 27     def select_car(self, car_type):
 28         return STNFactory().select_car_by_type(car_type)
 29 
 30 
 31 # 雪佛兰4S店
 32 class XFLStore(Store):
 33     def select_car(self, car_type):
 34         return XFLFactory().select_car_by_type(car_type)
 35 
 36 
 37 # 宝马工厂
 38 class BMFactory(object):
 39     def select_car_by_type(self, car_type):
 40         if car_type == "宝马X": return BaoMaX()
 41         if car_type == "宝马XX": return BaoMaXX()
 42         if car_type == "宝马XXX": return BaoMaXXX()
 43 
 44 
 45 # 桑塔纳工厂
 46 class STNFactory(object):
 47     def select_car_by_type(self, car_type):
 48         if car_type == "桑塔纳Q": return SangTaNaQ()
 49         if car_type == "桑塔纳QQ": return SangTaNaQQ()
 50 
 51 
 52 # 雪佛兰工厂
 53 class XFLFactory(object):
 54     def select_car_by_type(self, car_type):
 55         if car_type == "雪佛兰T": return XueFuLanT()
 56         if car_type == "雪佛兰TT": return XueFuLanTT()
 57 
 58 
 59 # 整个车类
 60 class Car(object):
 61     def move(self):
 62         print("车在移动......")
 63 
 64     def music(self):
 65         print("车里再放音乐....")
 66 
 67     def stop(self):
 68         print("车停下了.......")
 69 
 70 
 71 # 宝马车类
 72 class BaoMa(Car):
 73     pass
 74 
 75 
 76 class BaoMaX(BaoMa):
 77     pass
 78 
 79 
 80 class BaoMaXX(BaoMa):
 81     pass
 82 
 83 
 84 class BaoMaXXX(BaoMa):
 85     pass
 86 
 87 
 88 # 桑塔纳车类
 89 class SangTaNa(Car):
 90     pass
 91 
 92 
 93 class SangTaNaQ(SangTaNa):
 94     pass
 95 
 96 
 97 class SangTaNaQQ(SangTaNa):
 98     pass
 99 
100 
101 # 雪佛兰车类
102 class XueFuLan(Car):
103     pass
104 
105 
106 class XueFuLanT(XueFuLan):
107     pass
108 
109 
110 class XueFuLanTT(XueFuLan):
111     pass
112 
113 
114 stor = BMStore()
115 s = stor.Order("宝马XX")
116 s.move()
117 s.music()
118 s.stop()

简单工厂模式案例:
 1 # -*- coding: utf-8 -*-
 2 
 3 # 声明字符编码
 4 # coding:utf-8
 5 
 6 
 7 #<region 简单工厂模式>
 8 
 9 # 店铺类
10 class CarStore(object):
11     def __init__(self):
12         self.factory = Factory()
13     def Order(self,car_type):
14         return self.factory.select_car_by_type(car_type)
15 
16 
17 # # 店铺类
18 # class CarStore(object):
19 #     def Order(self,car_type):
20 #         return select_car_by_type(car_type)
21 
22 
23 
24 class Factory(object):
25     def select_car_by_type(self,car_type):
26         if car_type =="宝马":return BaoMa()
27         if car_type == "桑塔纳":return SangTaNa()
28         if car_type == "雪佛兰":return XueFuLan()
29 
30 # # 函数(达到了解耦性)
31 # def select_car_by_type(car_type):
32 #     if car_type =="宝马":return BaoMa()
33 #     if car_type == "桑塔纳":return SangTaNa()
34 #     if car_type == "雪佛兰":return XueFuLan()
35 
36 # 整个车类
37 class Car(object):
38     def move(self):
39         print("车在移动......")
40     def music(self):
41         print("车里再放音乐....")
42     def stop(self):
43         print("车停下了.......")
44 
45 
46 # 宝马车类
47 class BaoMa(Car):
48     pass
49 # 桑塔纳车类
50 class SangTaNa(Car):
51     pass
52 # 雪佛兰车类
53 class XueFuLan(Car):
54     pass
55 
56 
57 
58 
59 stor = CarStore()
60 s = stor.Order("宝马")
61 s.move()
62 s.music()
63 s.stop()
64 
65 #<endregion>