当前位置: 移动技术网 > IT编程>脚本编程>Python > Python学习笔记【第十一篇】:Python面向对象高级

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

2018年07月21日  | 移动技术网IT编程  | 我要评论

秀智bigbang,快门3d,情人节惊喜

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

 

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

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

 

 工厂模式案例:

  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>

 

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网