zoukankan      html  css  js  c++  java
  • 13.关于继承封装,以及反射

    # 描述符
    
    
      1  1 下面这个示例可以展现多态的某些功能
      3   class Water(object):
      4   2     def __init__(self, name, template):
      5   3         self.name = name
      6   4         self.template = template
      7   5 
      8   6     def wendu(self):
      9   7         if self.template < 0:
     10   8             print("%s由是变成了冰" % self.name)
     11   9         elif (self.template > 0 and self.template < 100):
     12  10             print("%s我是水" % self.name)
     13  11         elif self.template > 100:
     14  12             print("%s水变成了水蒸气" % self.name)
     15  13 
     16  14 
     17  15 class Ice(Water):
     18  16     pass
     19  17 
     20  18 
     21  19 class Shui(Water):
     22  20     pass
     23  21 
     24  22 
     25  23 class ZhengQi(Water):
     26  24     pass
     27  25 
     28  26 
     29  27 i = Ice("bing", -1)
     30  28 s = Shui("shui", 20)
     31  29 z = ZhengQi("zhengqi", 110)
     32  30 
     33  31 # i.wendu()
     34  32 # s.wendu()
     35  33 # z.wendu()
     36  34 
     37  35 
     38  36 # 继承(扩展和改变),多态(子类继承父类的方法,一种类经过不同的引用表现出来的多种形式)
     39  37 
     40  38 
     41  39 class Person(object):
     42  40     __star = "air"
     43  41 
     44  42     def __init__(self, name):
     45  43         self.name = name
     46  44         print(self.__star)
     47  45 
     48  46     def name1(self):
     49  47         return self.name
     50  48 
     51  49     def get_star(self):  # 访问函数
     52  50         return self.__star
     53  51 
     54  52 
     55  53 class Son(Person):
     56  54     def __init__(self, name):
     57  55         super(Son, self).__init__(name)
     58  56 
     59  57 
     60  58 s = Son("body")
     61  59 # print(s.name1())
     62  60 # 封装(分出内外,__name)
     63  61 
     64  62 # p = Person("bob")
     65  63 # print(Person.__dict__)
     66  64 # print(Person._Person__star)
     67  65 
     68  66 # print(hasattr(s, "name"))
     69  67 # print(hasattr(s, "name1"))  # 对象是否可以.到字符串中的属性
     70  68 #
     71  69 # func = getattr(s, "name2", None)
     72  70 # print(func)
     73  71 #
     74  72 # setattr(s, "age", 12)
     75  73 # setattr(s, "func", lambda self: self.age + 1)
     76  74 # print(s.func(s))
     77  75 # print(s.__dict__)
     78  76 #
     79  77 # delattr(s, "age")
     80  78 # print(s.__dict__)
     81  79 
     82  80 
     83  81 # 反射
     84  82 if hasattr(s, "get"):
     85  83     func_get = getattr(s, "get")
     86  84     func_get()
     87  85 else:
     88  86     pass
     89  87     # print("其他逻辑")
     90  88 
     91  89 test = __import__("t2")
     92  90 # print(test.config['DEFAULT']['ForwardX11'])
     93  91 #
     94  92 # import importlib
     95  93 # test1 = importlib.import_module("web.apps")
     96  94 # print(test1)
     97  95 
     98  96 
     99  97 class FOO:
    100  98     x = 1
    101  99 
    102 100     # 此类中的__XXXattr__方法与类无关,是属性的方法
    103 101     def __init__(self, y):
    104 102         self.y = y
    105 103 
    106 104     # 调用一个对象不存在的方法的时候才会执行
    107 105     def __getattr__(self, item):
    108 106         print("执行__getattr__")
    109 107         print("属性%s" %item + "不存在")
    110 108 
    111 109     def __delattr__(self, item):  # del f1.y
    112 110         print("删除了一个对象属性__delattr__")
    113 111         self.__dict__.pop(item)
    114 112 
    115 113     def __setattr__(self, key, value):  # f1.m=3
    116 114         print("__str__执行了")
    117 115         if type(value) is not str:
    118 116             print("%s不是字符串" % value)
    119 117         self.__dict__["key"] = value
    120 118 
    121 119 
    122 120 # f1 = FOO(10)
    123 121 # f1.name = "alex"
    124 122 # f1.age = 10
    125 123 # print(f1.__dict__)
    126 124 
    127 125 
    128 126 # 二次加工的数据类型
    129 127 class List(list):   # 继承了list之后 List("ss") = list("ss")
    130 128     def append(self, object):
    131 129         if type(object) is str:
    132 130             super().append(object)   # 这里调用父类的append方法,因为调用自己的append会导致循环引用的错误
    133 131         pass
    134 132 
    135 133     def show_middle(self):
    136 134         middle = int(len(self) / 2)
    137 135         return self[middle]
    138 136 
    139 137 
    140 138 # l1 = List("hello ! world")
    141 139 # print(l1)
    142 140 # print(l1.show_middle())
    143 141 # l1.append("ss")
    144 142 # print(l1)
    145 143 
    146 144 class Open(object):
    147 145 
    148 146     def __init__(self, filename, mode="r", encoding="utf-8"):
    149 147         # self.filename = filename
    150 148         self.file = open(filename, mode, encoding=encoding)
    151 149         self.mode = mode
    152 150         self.encoding = encoding
    153 151 
    154 152     def write(self, content):
    155 153         import time
    156 154         t1 = time.localtime()
    157 155         t = time.strftime("%Y-%m-%d %H:%M:%S", t1)  #  时间格式化
    158 156         print(time.strptime(t, "%Y-%m-%d %H:%M:%S"))
    159 157         self.file.write(str(t) + content)
    160 158 
    161 159     def __getattr__(self, item):
    162 160         print("%s不存在" % item)
    163 161         return getattr(self.file, item)  # 拿取属性中的file实例化的方法,当在当前类中不存在这个属性或者方法的时候
    164 162 
    165 163 
    166 164 # path = r"C:\Users\lzh\PycharmProjects\day05\a.txt"
    167 165 # f1 = Open(path, "w+")
    168 166 # print(f1.file)
    169 167 # print(f1.read)
    170 168 # f1.write("ssssssssssssssssss")
    171 169 
    172 170 
    173 171 import sys
    174 172 obj1 = sys.modules[__name__]  # 可以用来获取当前模块
    175 173 getattr(obj1, "get")

    2.描述符

      1 class Foo:
      2     def __init__(self, x):
      3         self.x = x
      4 
      5     def __getattr__(self, item):  # 当__getattribute__抛出AttributeError异常的时候才会执行
      6         print("__getattr__方法执行了")
      7 
      8     def __getattribute__(self, item):  # 不管找不找得到它都会执行
      9         print("__getattribute__方法执行了")
     10         raise AttributeError("出现错误")  # 只有抛出这个错误的时候__getattr__方法才会执行
     11 
     12 
     13 # f1 = Foo(12)
     14 # f1.xxx
     15 
     16 
     17 class Foo:
     18     pass
     19 
     20 
     21 class Bar(Foo):
     22     pass
     23 
     24 
     25 # b = Bar()
     26 # print(isinstance(b, Bar))
     27 # print(isinstance(b, Foo))  # b是否是Foo中的类实例化的
     28 # print(type(b))
     29 
     30 
     31 class Foo:
     32     # __XXXitem__是字典的方式,操作需要使用[]
     33     def __getitem__(self, item):   # 获取的时候调用
     34         print("getitem")
     35         return self.__dict__[item]
     36 
     37     def __setitem__(self, key, value):  # 设置的时候调用
     38         print("setitem")
     39         self.__dict__[key] = value
     40 
     41     def __delitem__(self, key):   # 删除的时候调用
     42         print("delitem")
     43         self.__dict__.pop(key)
     44 
     45 
     46 # f1 = Foo()
     47 # f1["name"] = "alex"
     48 # f1["age"] = 18
     49 # print(f1.__dict__)
     50 # del f1["name"]
     51 # print(f1.__dict__)
     52 # print(f1["age"])
     53 
     54 
     55 # 自定制显示
     56 l = list('name')
     57 # print(l)
     58 
     59 
     60 class Car(object):
     61 
     62     def __init__(self, name, age):
     63         self.name = name
     64         self.age = age
     65 
     66     # def __str__(self):   # 实例输出的时候,显示的问题
     67     #     return "你好啊{}".format(self.name)
     68 
     69     def __repr__(self):
     70         return "你好啊{}".format(self.name)
     71 
     72 
     73 c1 = Car("tom", 12)
     74 # print(c1)  # print(f1) ---->f1.__str__----->(如果没找到执行)f1.__repr__
     75 
     76 
     77 class Data:
     78     def __init__(self, year, mon, day):
     79         self.year = year
     80         self.mon = mon
     81         self.day = day
     82 
     83 
     84 d = Data(1019, 12, 12)
     85 
     86 x = "{0.year}{0.mon}{0.day}".format(d)
     87 # print(x)
     88 
     89 
     90 # 自定制format
     91 data_format = {
     92     "ymd": "{0.year}{0.mon}{0.day}",
     93     "y-m-d": "{0.year}-{0.mon}-{0.day}",
     94     "y:m:d": "{0.year}:{0.mon}:{0.day}",
     95     "y/m/d": "{0.year}/{0.mon}/{0.day}",
     96 
     97 }
     98 
     99 
    100 class Data1:
    101     def __init__(self, year, mon, day):
    102         self.year = year
    103         self.mon = mon
    104         self.day = day
    105 
    106     def __format__(self, format_spec=None):  # 定义返回格式
    107         if not format_spec or format_spec not in data_format:
    108             return data_format["ymd"].format(self)
    109         return data_format[format_spec].format(self)
    110 
    111 
    112 d1 = Data1(2019, 8, 5)
    113 # print(format(d1, "y-m-d"))
    114 
    115 
    116 class Tpp:
    117     """你好啊"""
    118     # 限制添加属性,只能改变__slots__中的属性(省内存,不常用)
    119     __slots__ = ["name", 'age']  # {"name": None, "age": None}
    120 
    121 
    122 t1 = Tpp()
    123 t1.age = 18  # t1.__setattr__----->fl.__dict__["age"]=18
    124 # print(t1.age)
    125 # print(t1.__slots__)
    126 # print(t1.__doc__)
    127 # __module__(查看创建实例的类在哪个模块)和__class__(查看实例是哪个类创建的)
    128 
    129 
    130 class A:
    131     def __init__(self):
    132         self.name = "liu"
    133 
    134     def __del__(self):  # 当时(实例)被删除的时候执行
    135         print("析构函数执行了")
    136 
    137 
    138 # a1 = A()
    139 # del a1.name
    140 # print("____________>")
    141 
    142 
    143 class A1:
    144     def __init__(self):
    145         self.name = "liu"
    146 
    147     def __call__(self, *args, **kwargs):  # 当实例加()执行时,调用这个方法
    148         print("实例执行了, obj()")
    149         # return self.name
    150 
    151     def __str__(self):
    152         return self.name
    153 
    154 
    155 a2 = A1()
    156 print(a2())  # A1的__call__方法
    157 A1()()  # abc(假设)的__call__(类加A1()()也可以执行)
    158 
    159 
    160 # 1.迭代器协议:对象必须有一个next方法,执行该方法要么返回迭代中的下一项,
    161 # 要么就引起一个StopIteration异常,用来终止迭代
    162 # 2.可迭代对象:实现了迭代器协议的对象(如何实现,对象内部顶一个__iter__方法)
    163 # 3.协议是一种约定,可迭代对象实现了迭代器协议,python的内部工具
    164 # (如for循环,sum,mi,max等函数)使用迭代器协议访问对象
    165 
    166 class Abb:
    167     def __init__(self, n):
    168         self.n = n
    169 
    170     def __iter__(self):  # 遍历时检查是否有这个方法
    171         return self
    172 
    173     def __next__(self):   # 执行next()或者遍历的时候执行
    174         self.n += 1
    175         if self.n > 13:
    176             raise StopIteration("没了")
    177         return self.n
    178 
    179 
    180 aa1 = Abb(10)
    181 # for i in aa1:  # aa1.__iter__
    182 # print(i)
    183 
    184 
    185 class Fib:
    186     def __init__(self):
    187         self.n = 1
    188         self.m = 1
    189 
    190     def __iter__(self):
    191         return self
    192 
    193     def __next__(self):
    194         self.m, self.n = self.n, self.n + self.m
    195         return self.m
    196 
    197 
    198 # f1 = Fib()
    199 # print(next(f1))
    200 # print(next(f1))
    201 # print(next(f1))
    202 # print(next(f1))
    203 # print(next(f1))
    204 
    205 
    206 # 描述符
    207 class Mn:
    208     def __init__(self, name):
    209         self.name = name
    210 
    211     def __get__(self, instance, owner):
    212         print(self.name, "111111111", instance, "aaa", owner, 'a')
    213 
    214     # def __set__(self, instance, value):
    215     #     print(self, instance, value, 'b')
    216     #     instance.__dict__["x"] = value
    217 
    218     # def __delete__(self, instance):
    219     #     print(instance, 'c')
    220 
    221 
    222 # 1.类属性
    223 # 2.数据描述符
    224 # 3.实例属性
    225 # 4.非数据描述符
    226 # 5.找不到的属性触发__getattr__()
    227 class Uoo:
    228     x = Mn("hua")  # 描述符, 代理属性,归代理管
    229 
    230     # def __init__(self, n):
    231     #     self.x = n
    232 
    233 
    234 u1 = Uoo()
    235 u1.x = 100  # 实例属性被描述符覆盖
    236 # print(u1.__dict__)
    237 # print(u1.x)
    238 # Uoo.x = 1
    239 # print(Uoo.__dict__)  # 描述符类属性被覆盖了
    240 
    241 
    242 # 上下文
    243 class Doo:
    244     def __init__(self, name):
    245         self.name = name
    246 
    247     def __enter__(self):
    248         print("执行enter")
    249         return self
    250 
    251     def __exit__(self, exc_type, exc_val, exc_tb):
    252         print("执行exit")
    253         print(exc_type)  # 错误类型
    254         print(exc_val)  # 错误值
    255         print(exc_tb)  # 错误的追踪信息
    256         return True  # 程序报出的一场会被隐藏掉
    257 
    258 
    259 # with Doo("a.txt") as f:  # 1. __enter__(),拿到返回值 == obj.__enter__()
    260 # #     print(f)
    261 # #     print(AFSDFSD)  # 2. 触发错误__exit__执行,打印错误
    262 # #     # print(f.name)   #
    263 # # print("==========>")
    264 
    265 # 描述符应用(用来限制传入的值)
    266 def test(x):
    267     print("===>", x)
    268 
    269 
    270 # test(10)
    271 
    272 class Typed:
    273     def __init__(self, key, except_type):
    274         self.key = key
    275         self.except_type = except_type
    276 
    277     def __get__(self, instance, owner):
    278         print("get")
    279         print(instance, "instance")
    280         print(owner, "owner")
    281         return instance.__dict__[self.key]
    282 
    283     def __set__(self, instance, value):
    284         print("set")
    285         print(instance, "instance")
    286         print(value, "value")
    287         if not isinstance(value, self.except_type):
    288             raise TypeError("{0}不是{1}类型".format(self.key, self.except_type))
    289         instance.__dict__[self.key] = value
    290 
    291     def __delete__(self, instance):
    292         print("delete")
    293         print(instance, "instance")
    294         instance.__dict__.pop(self.key)
    295 
    296 
    297 class People:
    298     name = Typed("name", str)
    299     age = Typed("age", int)
    300 
    301     def __init__(self, name, age, salary):
    302         self.name = name
    303         self.age = age
    304         self.salary = salary
    305 
    306 
    307 # p1 = People("name", 12, 7000.00)
    308 # print(p1.__dict__)
    309 
    310 
    311 # 类的装饰器
    312 def deco1(**kwargs):
    313     def deco(obj):
    314         print("======>", kwargs)
    315         for key, value in kwargs.items():
    316             setattr(obj, key, value)
    317         return obj
    318     print("=====>", kwargs)
    319     return deco
    320 
    321 
    322 @deco1(name="name", age=12)  # Poo==deco(Poo)
    323 class Poo:
    324     pass
    325 
    326 
    327 p1 = Poo()
    328 print(Poo.__dict__)

     3.使用描述符实现property装饰器(可以看另外一篇随笔,https://www.cnblogs.com/liuzhanghao/p/11089653.html 关于python的双下划线方法),借用了其他人的一篇文章链接,我也是看这个的,这个老师的课程非常好,有兴趣可以多做了解。

      1 # 装饰器加上描述符
      2 def deco1(**kwargs):
      3     def deco(obj):
      4         for key, value in kwargs.items():
      5             value = Typed(key, value)
      6             setattr(obj, key, value)
      7         return obj
      8     return deco
      9 
     10 
     11 @deco1(name=str, age=int)
     12 class People1:
     13     # name = Typed("name", str)
     14     # age = Typed("age", int)
     15 
     16     def __init__(self, name, age, salary):
     17         self.name = name
     18         self.age = age
     19         self.salary = salary
     20 
     21 
     22 # pp1 = People1("name", 12, 123)
     23 
     24 
     25 # 利用描述符字典纸property
     26 class LazyProperty:
     27     def __init__(self, fun):
     28         print("=====>", fun)
     29         self.fun = fun
     30 
     31     def __get__(self, instance, owner):  # 只加__get__就是实例属性
     32         print("get")
     33         # print(self)
     34         # print(instance)
     35 
     36         if instance == None:
     37             return self
     38         # 不需要下面三行代码的原因是,设置到实例属性的字典中之后,他下次取就从属性字典中取,
     39         # 所以不需要下面的判断
     40         # if hasattr(instance, self.fun.__name__):
     41         #     res = self.__dict__[self.fun.__name__]
     42         # else:
     43         res = self.fun(instance)
     44         setattr(instance, self.fun.__name__, res)
     45         return res
     46 
     47     def __set__(self, instance, value):  # 加上__set__就是数据描述符,只比类属性优先级低
     48         print("set")
     49 
     50 
     51 class Room:
     52     def __init__(self, width, length, name):
     53         self.name = name
     54         self.length = length
     55         self.width = width
     56 
     57     @LazyProperty
     58     def area(self):   # area = LazyProperty(area)
     59         return self.length * self.width
     60 
     61     @property
     62     def area1(self):
     63         return self.length * self.width
     64 
     65     @area1.setter
     66     def area1(self, val):
     67         print("set的时候运行", val)
     68 
     69     @area1.deleter
     70     def area1(self, key):
     71         print("del的时候运行", key)
     72 
     73 
     74 r1 = Room(100, 100, "liu")
     75 # print(Room.__dict__)
     76 # print(r1.area)
     77 """
     78 大概解释一下,自定值property的流程,因为在这之前,我从来没有想过这样做
     79 1.在加载类的时候,会执行__init__方法,在执行到area方法的时候,会先执行@LazyProperty方法,等价于
     80 area = LazyProperty(area),可以理解就是一个描述符(而描述符必须包含__get__,__set__,__delete__中的一种,
     81 所以我们写了一个__get__方法),代理了area方法,可以看到LazyProperty(area),将area方法名传入了其中,
     82 所有我们需要在LazyProperty中写一个__init__方来接收参数,这时初始化时的加载已经完成
     83 2.当我们在实例化完成之后,r1.area的时候其实就调用了LazyProperty描述符的__get__方法,要实现自定义的property
     84 肯定需要执行r1.area()的方法,并且返回值。我们需要则么做呢?有没有记得第一步中LazyProperty的__init__方法,
     85 我们传过去了什么呢?LazyProperty(area)其实就是将area方法传入了描述符中,呢么我们只需要在实例r1.area调用
     86 描述符的__get__方法的时候,执行这个方法,反回结果就可以了,return self.fun(instance)(对于__get__(instance, owner),
     87 中的instance代表的是实例r1,owner代表的则是Room类<也就是r1通过哪个类实例的>)
     88 """
     89 
     90 # 类调用
     91 # print(Room.test)
     92 
     93 # print(r1.area)
     94 r1.area1 = 1000
     95 
     96 
     97 class Boom:
     98     def __init__(self, width, length, name):
     99         self.name = name
    100         self.length = length
    101         self.width = width
    102 
    103     @LazyProperty
    104     def area(self):   # area = LazyProperty(area)
    105         return self.length * self.width
    106 
    107     def get_area1(self):
    108         return self.length * self.width
    109 
    110     def set_area1(self, val):
    111         print("set的时候运行", val)
    112 
    113     def del_area1(self, key):
    114         print("del的时候运行", key)
    115 
    116     area1 = property(get_area1, set_area1, del_area1)
     1 # 元类
     2 class Foo:
     3     pass
     4 
     5 
     6 f1 = Foo()
     7 # print(type(f1))
     8 # print(type(Foo))
     9 
    10 
    11 def __init__(self, name, age):
    12     self.name = name
    13     self.age = age
    14 
    15 
    16 def test(self):
    17     print("====》")
    18 
    19 
    20 FFo = type("FFo", (object, ), {"x": 1, "__init__": __init__, "test": test})
    21 # print(FFo)
    22 # print(FFo.__dict__)
    23 
    24 
    25 # 控制类的生成过程
    26 class MyType(type):
    27 
    28     def __init__(self, clazname, bases, attrs):
    29         """
    30         :param clazname:  类名  Nll
    31         :param bases:   继承的类  ()
    32         :param attrs:   属性和方法  __dict__
    33         """
    34         # print("指定元类的生成")
    35         pass
    36     
    37     def __call__(self, *args, **kwargs):
    38         """
    39         :param self: 调用这个方法的《类》对象
    40         :param args:  传入类的属性
    41         :param kwargs: 传入类的属性
    42         :return:
    43         """
    44         obj = object.__new__(self)  # object.__new__(Foo)  n1
    45         self.__init__(obj, *args, **kwargs)  # Nll.__init__()
    46         return obj
    47 
    48 
    49 class Nll(metaclass=MyType):  # Nll = MyType(self, "Nll", (), {}) ---->__init__
    50     def __init__(self, name):
    51         self.name = name
    52 
    53 
    54 # n1 = Nll(name="pass")
    55 # print(n1)
    56 # print(n1.__dict__)
    57 
    58 
    59 # 异常处理
    60 # 语法错误,逻辑错误
    61 try:
    62     # age = input("===>")
    63     int(12)
    64 
    65 except ValueError as e:
    66     print("值错误")
    67 except Exception as e:
    68     print("出现错误")
    69 
    70 # else:
    71 #     print("没有异常执行")
    72 # finally:
    73 #     print("不管有没有异常,都会执行finally下的代码")
    74 
    75 
    76 class CustomException(BaseException):
    77     def __init__(self, message):
    78         self.message = message
    79 
    80 
    81 # print(CustomException("自定义异常"))
  • 相关阅读:
    URLEncode解决url中有特殊字符的问题
    监控系统概览
    SpringBoot 上传文件夹
    关于postgresql报 ERROR: XXX does not exist
    postgresql学习
    git学习
    学习博客
    面试准备
    jvm
    线程池面试题
  • 原文地址:https://www.cnblogs.com/liuzhanghao/p/11290291.html
Copyright © 2011-2022 走看看