我们知道,在不改变原有代码的基础上,我们可以使用装饰器为函数添加新的功能。同理,一切皆对象,我们也可以使用装饰器为类添加类属性。what?

  

def deco(obj):
obj.x = 1
obj.y = 2
return obj @deco # Foo = deco(Foo)
class Foo:
pass print(Foo.__dict__)

上述的代码为Foo属性字典添加了x和y属性,但如果想添加'name' = 'harden'呢,这需要更灵活的定义了。so

def deco(**kwargs):

    def wrapper(obj):
for k, v in kwargs.items():
setattr(obj, k, v)
return obj
return wrapper @deco(x=1, y=2)
class Foo:
pass print(Foo.__dict__)
{'__module__': '__main__', '__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None, 'x': 1, 'y': 2}

我们再定义类Bar,

@deco(name='curry')
class Bar:
pass

name属性也可以添加进去

再来个升级版,利用数据描述符和类的装饰器为类属性限定数据类型

我们知道,在不改变原有代码的基础上,我们可以使用装饰器为函数添加新的功能。同理,一切皆对象,我们也可以使用装饰器为类添加类属性。what?

  

def deco(obj):
obj.x = 1
obj.y = 2
return obj @deco # Foo = deco(Foo)
class Foo:
pass print(Foo.__dict__)
上述的代码为Foo属性字典添加了x和y属性,但如果想添加'name' = 'harden'呢,这需要更灵活的定义了。so def deco(**kwargs): def wrapper(obj):
for k, v in kwargs.items():
setattr(obj, k, v)
return obj
return wrapper @deco(x=1, y=2)
class Foo:
pass print(Foo.__dict__)
{'__module__': '__main__', '__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None, 'x': 1, 'y': 2}
我们再定义类Bar, @deco(name='curry')
class Bar:
pass
name属性也可以添加进去 再来个升级版,利用数据描述符和类的装饰器为类属性限定数据类型 #数据描述符,代理另一个新式类的属性
class Typedef: def __init__(self, key, expected_type):
self.key = key
self.expected_type = expected_type def __get__(self, instance, owner):
# print('exec __get__')
# print(instance)
# print(owner)
return instance.__dict__[self.key] def __set__(self, instance, value):
# print('exec __set__')
if not isinstance(value, self.expected_type):
raise TypeError
instance.__dict__[self.key] = value def __delete__(self, instance):
instance.__dict__.pop(self.key) def deco(**kwargs):
def wrapper(obj):
for k, v in kwargs.items():
       #为obj添加属性 如 name = Tpyedef('name', str)
setattr(obj, k, Typedef(k, v))
return obj
return wrapper @deco(name=str, age=int, salary=float) # =====》People= wrapper(People)
class People: def __init__(self, name, age, salary):
self.name = name
self.age = age
self.salary = salary p1 = People('handen', 18, 111.11)
print(p1.name)
print(p1.__dict__)

python 类的装饰器的更多相关文章

  1. 第7.18节 案例详解:Python类中装饰器@staticmethod定义的静态方法

    第7.18节 案例详解:Python类中装饰器@staticmethod定义的静态方法 上节介绍了Python中类的静态方法,本节将结合案例详细说明相关内容. 一.    案例说明 本节定义了类Sta ...

  2. python 类内部装饰器的实现 与 参数解构学习

    学习了函数的装饰器的写法,然后想到如果要在类中初始化或获取信息时能用装饰器做过滤和验证应该怎么写呢, 在网上查了下相关信息,感觉这样也是可以的,不知道会不会有什么问题class Ctj(): clas ...

  3. Python类中装饰器classmethod,staticmethod,property,

    @classmethod 有的时候在类中会有一种情况,就是这个方法并不需要使用每一个对象属性 因此 这个方法中的self参数一个完全无用的参数,使用classmethod class A: __cou ...

  4. python类常用装饰器

    class Myclass(object): def __init__(self): pass #必须实例化才能调用 def sayhi(self): print 'hello' #静态方法,跟类没什 ...

  5. python描述符(descriptor)、属性(property)、函数(类)装饰器(decorator )原理实例详解

     1.前言 Python的描述符是接触到Python核心编程中一个比较难以理解的内容,自己在学习的过程中也遇到过很多的疑惑,通过google和阅读源码,现将自己的理解和心得记录下来,也为正在为了该问题 ...

  6. 11.python描述符---类的装饰器---@property

    描述符1.描述符是什么:描述符本质就是一个新式类,在这个新式类中,至少实现了__get__(),__set__(),__delete__()这三个内置方法中的一个,描述符也被称为描述符协议(1):__ ...

  7. Python之路(第二十八篇) 面向对象进阶:类的装饰器、元类

    一.类的装饰器 类作为一个对象,也可以被装饰. 例子 def wrap(obj): print("装饰器-----") obj.x = 1 obj.y = 3 obj.z = 5 ...

  8. 详解Python闭包,装饰器及类装饰器

    在项目开发中,总会遇到在原代码的基础上添加额外的功能模块,原有的代码也许是很久以前所写,为了添加新功能的代码块,您一般还得重新熟悉源代码,稍微搞清楚一点它的逻辑,这无疑是一件特别头疼的事情.今天我们介 ...

  9. 面向切面编程AOP——加锁、cache、logging、trace、同步等这些较通用的操作,如果都写一个类,则每个用到这些功能的类使用多继承非常难看,AOP就是解决这个问题的,python AOP就是装饰器

    面向切面编程(AOP)是一种编程思想,与OOP并不矛盾,只是它们的关注点相同.面向对象的目的在于抽象和管理,而面向切面的目的在于解耦和复用. 举两个大家都接触过的AOP的例子: 1)java中myba ...

随机推荐

  1. VirtualBox搭建1主2从虚拟机

    环境要求 最近在使用VirtualBox搭建一个实验环境,由于公司规定了所有的机器都不能使用固定IP,都必须由DHCP自动获取. 为了不影响公司整理的网络环境,只能把实验用的网络环境限制在使用内部IP ...

  2. 执行linux脚本出现问题

    1. 权限不够: 使用 chmod +x XXX.sh 提升权限 2. 出现:/bin/bash^M: bad interpreter: No such file or directory 原因:文件 ...

  3. break跳出嵌套循环体

    package com.wh.Object; public class Test { public static void main(String[] args) { // TODO Auto-gen ...

  4. 转 ORA-00054 的解决方法

    统有一个不用的索引,想删除这个索引, SQL> drop index GPSTIME_GLOBAL_INDEX  2  /drop index GPSTIME_GLOBAL_INDEX      ...

  5. jquery判断checkbox最多选几个

    <!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8&qu ...

  6. Java线程-线程、程序、进程的基本概念

    线程 与进程相似,但线程是一个比进程更小的执行单位.一个进程在其执行的过程中可以产生多个线程. 与进程不同的是同类的多个线程共享同一块内存空间和一组系统资源,所以系统在产生一个线程,或是在各个线程之间 ...

  7. idea 调试工具的使用

    原文:https://blog.csdn.net/hao_hl1314/article/details/53120918 Intellij IDEA Debug调试区工具的使用方法 快捷键F9     ...

  8. [转] 随机数是骗人的,.Net、Java、C为我作证

    (转自:随机数是骗人的,.Net.Java.C为我作证 - 杨中科   原文日期:2014.05.12) 几乎所有编程语言中都提供了"生成一个随机数"的方法,也就是调用这个方法会生 ...

  9. 强大的云存储与应用管理工具DzzOffice1.0 Beta(大桌子办公)发布下载

    之前在9月份我们发布了一份内测版,得到了1000多位朋友参与下载测试.经过2个月,结合测试后朋友们反馈的问题,和开发建议.终于完成了这次Beta版的开发.感谢这两个月中参与测试,和帮助我们完善程序的朋 ...

  10. leetcode_650. 2 Keys Keyboard_dp

    https://leetcode.com/problems/2-keys-keyboard/ 初始一个A,两种操作,复制当前所有A,粘贴,问得到n个A最少需要多少步操作. class Solution ...