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

  类的装饰器.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. [转]html5调用摄像头实例

    原文:https://blog.csdn.net/binquan_liang/article/details/79489989 最近在学习在做HTML5的项目,看了博客上html5调用摄像头拍照的文章 ...

  2. Decoration2:引入Angularjs显示前台一条数据

    SpringMVC内置的RestFul API格式采用的是最复杂最全面的HATEOAS规范,对于简单应用来说,前台解析起来不方便,我们下面主要想办法重新定义一种简单的RestFulAPI. (1)先是 ...

  3. Linux下恢复误删文件:思路+实践

    周五篮球群里有人问误删文件了怎么恢复,得知是ext4文件系统之后我推荐了ext4magic这个工具,然后又有人提到了xfs的话怎么办,正好前几天看到Dave Chinner在邮件列表里提到了这个问题, ...

  4. python学习笔记(1)--遍历txt文件,正则匹配替换文字

    遍历一个文件夹,把里面所有txt文件里的[]里的朗读时间删除,也就是替换为空. import os import re import shutil #os文件操作,re正则,shutil复制粘贴 pa ...

  5. JVM系统性能监控总结

    (1) uptime 查看系统运行时间.连接数(终端连接数).平均负载 (2) top 查看CPU.内存.交换空间使用情况,可以看到当前系统性能进程消耗资源情况 (3) vmstat 统计系统CPU. ...

  6. redis-stat 安装

    apt-get install ruby     apt-get install rubygems redis-stat安装: cd/root git clone https://github.com ...

  7. PHP高并发的解决方案

    这几天面试,被问到这样一个问题:如何解决大流量的高并发问题.起初不知所措,在查阅相关资料,以及网上大牛们的解答之后,总结出以下几点: 1.服务器,如果同时访问量超过10W的话,需要采用专用服务器来承载 ...

  8. Android学习笔记36:使用SQLite方式存储数据

    在Android中一共提供了5种数据存储方式,分别为: (1)Files:通过FileInputStream和FileOutputStream对文件进行操作.具体使用方法可以参阅博文<Andro ...

  9. 转载 Python导入模块的几种姿势

    作为一名新手Python程序员,你首先需要学习的内容之一就是如何导入模块或包.但是我注意到,那些许多年来不时使用Python的人并不是都知道Python的导入机制其实非常灵活.在本文中,我们将探讨以下 ...

  10. 登陆Oracle11g的企业管理器

    本地:https://localhost:1158/em/ 如果远程:那么把localhost换成服务器IP