zoukankan      html  css  js  c++  java
  • Python学习笔记【第十一篇】: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("
     ==============对象的反射============ 
    ")
    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("
     ==============类的反射(类本质上也是对象)============ 
    ")
    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 + "
    "))
    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("
    ======系统内置property=====
    ")
    41     p1 = Person('王二小', 12, '', '中国')
    42     p1.say
    43     print("
    ======自定义的property=====
    ")
    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>
  • 相关阅读:
    Python爬虫入门教程 59-100 python爬虫高级技术之验证码篇5-极验证识别技术之二
    CouchDB简介
    零成本打造抖音IP,轻松实现月入过万,90%的人都不懂
    couchdb集群搭建
    汽车测评详细操作流程,一篇赚300+
    基于docker部署的微服务架构: docker环境下的zookeeper和kafka部署
    零成本的互联网赚钱项目,都是怎么做的?
    SQuirrel连接hive配置
    本人有8万启动资金,做点什么生意好呢?
    PHP实现自己活了多少岁
  • 原文地址:https://www.cnblogs.com/wendj/p/9341410.html
Copyright © 2011-2022 走看看