类是一个对象也可以像函数一样加装饰器

  类的装饰器.py

def deco(obj):
print('======',obj)
obj.x=1
obj.y=2
obj.z=3
return obj # @deco #test=deco(test)
# def test():
# print('test函数运行') #运行了装饰器所以打印了装饰器里面的print内容
@deco #Foo=deco(Foo)
#======
class Foo:
pass

#打印类的字典,其中xyz属性是在装饰器函数里面定义的
print(Foo.__dict__)
#{'__doc__': None, 'z': 3, 'y': 2, '__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, 'x': 1, '__module__': '__main__'}

  本装饰器就是把类作为实参传递给函数deco然后把返回值赋值给Foo,在装饰器函数里面可以定义对应类的属性

  以上装饰器虽然在装饰器里面实现了对类属性进行赋值但是把赋值写死了

  下面通过嵌套把装饰器写的灵活

  类的装饰器2.py

#定义装饰器函数deco函数接受参数为字典格式
def deco(**kwargs):
def wrapper(obj):
print('--->',kwargs)
#---> {'y': 2, 'z': 3, 'x': 1}
print('类名--->',obj)
#类名---> <class '__main__.Foo'>
for key,val in kwargs.items():
setattr(obj,key,val)
return obj
print('===>',kwargs)
#===> {'y': 2, 'z': 3, 'x': 1}
return wrapper
#在原装饰器deco嵌套一个内部函数wrapper
#执行步骤
#1,deco(x=1,y=2,z=3)执行函数deco返回的是函数wrapper
#2,@wrapper装饰类Foo 相当于把类Foo作为参数传递给函数wrapper然后再返回给Foo
#3,在函数wrapper内部执行对应的对类属性执行赋值操作使用了函数setattr,传递3个参数1位对象2为key3为value
@deco(x=1,y=2,z=3) #deco(x=1,y=2,z=3) -->@wrapper
class Foo:
pass print(Foo.x)
#1 #同理使用装饰器装饰另外一个类可以通过在装饰的时候传递参数实现对不同类装饰的定制
@deco(name='zhangsan')
class Bar:
pass #装饰成功打印正确
print(Bar.name)
#zhangsan

  类的装饰器的应用.py

class Typed:
def __init__(self,key,expected_type):
self.key=key
self.expected_type=expected_type
def __get__(self, instance, owner):
print('get方法')
# print('instance是[%s]'%instance)
# print('owner是[%s]'%owner)
#使用对应的key返回值
return instance.__dict__[self.key] def __set__(self, instance, value):
print('set方法')
#instance就是实例化出来的对象本身
# print('instance是[%s]'%instance)
# print('value是[%s]'%value)
#对应的key进行赋值设置操作
if not isinstance(value,self.expected_type):
# print('你输入是不是字符串类型,错误')
# return
raise TypeError('%s你传入的不是%s'%(value,self.expected_type))
instance.__dict__[self.key] = value def __delete__(self, instance):
print('delete方法')
# print('instance是[%s]' % instance)
#使用对应的key删除操作
instance.__dict__.pop(self.key) def deco(**kwargs):
def wrapper(obj):
for key,val in kwargs.items():
print('=====>',key,val)
#第一次循环key='name' val='str'
#相当于给类加了对应的类属性设置为描述符
#完成了之前People类里面的name = Typed('name',str)
setattr(obj,key,Typed(key,val))
return obj
return wrapper @deco(name=str,age=int)
class People:
# name = Typed('name',str)
# age = Typed('age',int)
def __init__(self,name,age,salary):
self.name = name
self.age = age
self.salary = salary p1=People('zhangsan',18,999999)
print(p1.__dict__)

  把之前通过描述符实现的对类型限制的功能使用装饰器实现,简化代码

  使用装饰器来给类属性添加一个属性,只不过这个属性比较特殊,是一个描述符

Python全栈day28(类的装饰器)的更多相关文章

  1. python 全栈开发,Day114(装饰器,排序规则,显示列,添加按钮,定制ModelForm,自定义列表页面,自定制URL)

    一.装饰器 装饰器本质上就是一个python函数,他可以让其他函数在不需要做任何代码变动的前提下,增加额外的功能,装饰器的返回值也是一个函数对象. 装饰器的应用场景:比如插入日志,性能测试,事务处理, ...

  2. Python使用偏函数与类实现装饰器

    # -*- coding: utf-8 -*- # author:baoshan # python对某个对象是否能通过装饰器形式使用只有一个要求:decorator必须是一个可被调用的对象. # 我们 ...

  3. Python全栈day28(描述符应用)

    描述符的使用 python是弱类型语言,及参数的赋值没有类型限制,下面通过描述符机制来实现类型限制功能 描述符应用1.py class Typed: def __get__(self, instanc ...

  4. Python全栈day28(上下文管理)

    我们知道在操作文件对象的时候可以这么写 with open('a.txt',''r) as f: 代码 上述叫做上下文管理协议,即with语句,为了让一个对象兼容with语句,必须在这个对象的类中声明 ...

  5. Python全栈之路8--迭代器(iter)和生成器(yield)

    一.生成器( iter ) 从Python2.2起,生成器提供了一种简洁的方式帮助返回列表元素的函数来完成简单和有效的代码. 它基于yield指令,允许停止函数并立即返回结果.此函数保存其执行上下文, ...

  6. Python全栈之路目录结构

    基础 1.Python全栈之路-----基础篇 2.Python全栈之路---运算符与基本的数据结构 3.Python全栈之路3--set集合--三元运算--深浅拷贝--初识函数 4.Python全栈 ...

  7. Python全栈工程师(装饰器、模块)

    ParisGabriel                每天坚持手写  一天一篇  决定坚持几年 全栈工程师     Python人工智能从入门到精通 装饰器 decorators(专业提高篇) 装饰 ...

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

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

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

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

随机推荐

  1. [svc]entrypoint.sh shell脚本解析

    最近搞influxdb绘图,看到其dockerfile的entry.sh,无奈看的不是很懂. 于是查了下.. docker run 通过传参实现配置文件覆盖 实现启动镜像时候可指定配置文件 如果不指定 ...

  2. JMeter学习笔记(三)

    D. User Defined Variables:用户自定义的变量,在此我们可以定义后面原件需要引用的变量并对其进行赋值.jsessionid一般是服务器返回的,每个用户返回的都不一样,所以在此不应 ...

  3. Tomcat7中开启gzip压缩功能的配置方法

    使用gzip压缩可以减少数据传输大小,加快网页加载速度.很多大站都开启了gzip压缩,不过也有很多网站并没有开启gzip压缩,上次看了一篇文章说开启gzip压缩后对搜索引擎不友好,但从带宽和流量的角度 ...

  4. locatin

    //location对象 //初始url:http://www.wrox.com/WileyCDA: //将URL修改为:http://www.wrox.com/WileyCDA/#section1 ...

  5. django model 多对多保存

  6. 一款纯html5实现的时钟

    今天给大家分享一款非常漂亮的纯html5实现的时钟.整个界面都由html5绘制而成.一起看下效果图: 在线预览   源码下载 实现的代码. html代码: <div class="co ...

  7. C - The C Answer (2nd Edition) - Exercise 1-2

    /* Experiment to find out what happens when printf's argument string contains \c, where c is some ch ...

  8. 《C++ Primer》笔记-#include,#ifndef

    1.理解 #include 指示是怎样工作的 #include 设 施是 C++ 预处理器的一部分.预处理器处理程序的源代码,在编译器之前运行. C++ 继承了 C 的非常精细的预处理器.现在的 C+ ...

  9. golang :连接数据库闲置断线的问题

    golang在进行数据库操作,一般来说我们使用Open函数创建一个数据库(操作)句柄:func Open(driverName, dataSourceName string) (*DB, error) ...

  10. JobTracker作业启动过程分析

    转自:http://blog.csdn.net/androidlushangderen/article/details/41356521 在Hadoop中,启动作业运行的方式有很多,可以用命令行格式把 ...