zoukankan      html  css  js  c++  java
  • Python进阶-----类的装饰器及应用

    回顾什么是装饰器:
      装饰器定义:本质就是函数(高阶函数),功能是为其他函数(对象)添加新功能

    一、类的装饰器基本实现原理如下:

    1 def deco(cls):
    2     print('类的装饰器=========》')
    3     print('='*20)
    4     return cls
    5 
    6 @deco      #====> Foo = deco(Foo)
    7 class Foo:
    8     pass

    二、上述的简单装饰器是没有参数的,现在我们加上参数

     1 def cls_decorator(**kwargs):            #支持传入参数(属性和对应的值),字典形式
     2     def deco(cls):
     3         for key,val in kwargs.items():
     4             setattr(cls,key,val)        #给类设置对应的属性和值
     5         return cls
     6     return deco
     7 
     8 @cls_decorator(name='Menawey',age=24,gender='male')        # 1 运行cls_decorator(...),返回deco;2 @deco===> Peolple = deco(People)
     9 #相当于给People类设置了name、age、gender属性
    10 class People:
    11     pass
    12 
    13 print(People.__dict__)                                   #查看被装饰过的类的属性字典

       通过这样就可以动态的给不同的类在他实例化前增加属性

    三、结合描述符
      通过描述符和类的装饰器组合使用,可以完成很多功能,比如为类添加属性,并且可以限定属性的类型。

     1 #描述符
     2 class Desc:
     3     def __init__(self,key,value_type):
     4         self.key = key
     5         self.value_type = value_type
     6     def __get__(self, instance, owner):
     7         return instance.__dict__[self.key]
     8     def __set__(self, instance, value):
     9         if not isinstance(value,self.value_type):
    10             raise TypeError('%s 传入的类型不是 %s'%(self.key,self.value_type))
    11         instance.__dict__[self.key] = value
    12     def __delete__(self, instance):
    13         instance.__dict__.pop(self.key)
    14 
    15 #装饰器
    16 def cls_decorator(**kwargs):            #支持传入参数(属性和对应的值),字典形式
    17     def deco(cls):
    18         for key,val in kwargs.items():    #这里需要用到描述符对属性进行代理,但是val是指定的类型,所以要用Desc(key,val)来描述为对应的值
    19             setattr(cls,key,Desc(key,val))        #给类设置对应的属性和值
    20         return cls
    21     return deco
    22 
    23 @cls_decorator(name=str,age=int,gender=str,salary=float)    #使用装饰器
    24 
    25 #被装饰和描述的类
    26 class People:
    27     def __init__(self,name,age,gender,salary):
    28         self.name = name
    29         self.age = age
    30         self.gender = gender
    31         self.salary = salary
    32 
    33 p1 = People('Menawey',24,'male',11.1)  #因为gender属性指定的是sstr,但是TypeError: age 传入的类型不是 <class 'int'>
    34 print(People.__dict__)
  • 相关阅读:
    我的插件框架·前传
    在OpenSUSE中听歌
    ASP.NET MVC 3.0 源码阅读手记(1)
    Mono on Linux 开发与实践札记(1)
    探讨对Web控件的异常处理
    进销存管理中负库存产生的原因以及对应措施
    看了一篇不错的文章 使用 UTF8 对 XML 文档进行编码
    进销存管理中对红冲处理的误区
    Ajax学习笔记(2) 一定要用XML吗?
    打造自己的Html文本编辑控件
  • 原文地址:https://www.cnblogs.com/Meanwey/p/9901998.html
Copyright © 2011-2022 走看看