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

  类的装饰器.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. atitit. 文件上传带进度条 atiUP 设计 java c# php

    atitit. 文件上传带进度条 atiUP 设计 java c# php 1. 设计要求 1 2. 原理and 架构 1 3. ui 2 4. spring mvc 2 5. springMVC.x ...

  2. atitit。解决 No suitable Log constructor。。NoClassDefFoundError: org/apache/log4j/Category 找不到类的

    atitit.解决 No suitable Log constructor..NoClassDefFoundError: org/apache/log4j/Category 找不到类的 1. 深的层次 ...

  3. Linux Shell编程之常用技巧

    前言 本文集中介绍了bash编程中部分高级编程方法和技巧.通过学习本文内容,可以帮你解决以下问题: 1.bash可以网络编程么? 2..(){ .|.& };. 据说执行这些符号可以死机,那么 ...

  4. JAX-WS使用Handler实现简单的WebService权限验证

    WebService如果涉及到安全保密或者使用权限的时候,WS-Security通常是最优选择.WS-Security (Web服务安全) 包含了关于如何在WebService消息上保证完整性和机密性 ...

  5. java 高精度 四则运算

    java的大数处理对于ACM中的大数来说,相当的简单啊: 整数的运算   BigInteger 小数的运算   BigDecimal 导入类: import java.util.Scanner; im ...

  6. 深入浅出MFC--第一章

    Windows程序的生与死 当使用者按下系统菜单中的Close命令项,系统送出WM_CLOSE.通常程序的窗口函数不拦截次消息,于是DefWindowProc函数处理它.DefWindowProc收到 ...

  7. kafka启动及查看topic命令【已用过的,待更新】

    以下均为开发测试环境下: 启动Zookeeperbin/zookeeper-server-start.sh config/zookeeper.properties &启动kafkabin/ka ...

  8. js delete

    在开始之前,先让我们看一段代码 >>> var sum = function(a, b) {return a + b;} >>> var add = sum; &g ...

  9. Bootstrap学习笔记(3)--菜鸟网CDN

    Bootstrap CDN 推荐 本站实例采用的是自建的静态资源库上的Bootstrap资源. <!-- 新 Bootstrap 核心 CSS 文件 --> <link href=& ...

  10. shell监控脚本,不考虑多用户情况

    #!/bin/bash CheckProcess() { if [ "$1" = "" ]; then fi PROCESS_NUM=`ps -ef | gre ...