Python全栈day28(类的装饰器)
类是一个对象也可以像函数一样加装饰器
类的装饰器.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(类的装饰器)的更多相关文章
- python 全栈开发,Day114(装饰器,排序规则,显示列,添加按钮,定制ModelForm,自定义列表页面,自定制URL)
一.装饰器 装饰器本质上就是一个python函数,他可以让其他函数在不需要做任何代码变动的前提下,增加额外的功能,装饰器的返回值也是一个函数对象. 装饰器的应用场景:比如插入日志,性能测试,事务处理, ...
- Python使用偏函数与类实现装饰器
# -*- coding: utf-8 -*- # author:baoshan # python对某个对象是否能通过装饰器形式使用只有一个要求:decorator必须是一个可被调用的对象. # 我们 ...
- Python全栈day28(描述符应用)
描述符的使用 python是弱类型语言,及参数的赋值没有类型限制,下面通过描述符机制来实现类型限制功能 描述符应用1.py class Typed: def __get__(self, instanc ...
- Python全栈day28(上下文管理)
我们知道在操作文件对象的时候可以这么写 with open('a.txt',''r) as f: 代码 上述叫做上下文管理协议,即with语句,为了让一个对象兼容with语句,必须在这个对象的类中声明 ...
- Python全栈之路8--迭代器(iter)和生成器(yield)
一.生成器( iter ) 从Python2.2起,生成器提供了一种简洁的方式帮助返回列表元素的函数来完成简单和有效的代码. 它基于yield指令,允许停止函数并立即返回结果.此函数保存其执行上下文, ...
- Python全栈之路目录结构
基础 1.Python全栈之路-----基础篇 2.Python全栈之路---运算符与基本的数据结构 3.Python全栈之路3--set集合--三元运算--深浅拷贝--初识函数 4.Python全栈 ...
- Python全栈工程师(装饰器、模块)
ParisGabriel 每天坚持手写 一天一篇 决定坚持几年 全栈工程师 Python人工智能从入门到精通 装饰器 decorators(专业提高篇) 装饰 ...
- python描述符(descriptor)、属性(property)、函数(类)装饰器(decorator )原理实例详解
1.前言 Python的描述符是接触到Python核心编程中一个比较难以理解的内容,自己在学习的过程中也遇到过很多的疑惑,通过google和阅读源码,现将自己的理解和心得记录下来,也为正在为了该问题 ...
- 11.python描述符---类的装饰器---@property
描述符1.描述符是什么:描述符本质就是一个新式类,在这个新式类中,至少实现了__get__(),__set__(),__delete__()这三个内置方法中的一个,描述符也被称为描述符协议(1):__ ...
随机推荐
- Maven的个性化定制
用Maven的小伙伴都知道,Maven的宗旨是约定优于配置(Convention Over Configuration). 在宗旨的前提下Maven也提供了个性化定制的Profile,让我们看看使用方 ...
- Objective-C函数重载规则
是按照函数标签是否重复来判断是否为一个重载函数的.
- 关于 initWithNibName 和 loadNibNamed 的区别和联系-iPhone成长之路
转自:http://blog.sina.com.cn/s/blog_7b9d64af01018f2u.html 关于 initWithNibName 和 loadNibNamed 的区别和联系.之所以 ...
- PaaS 平台的网络需求
在使用 Docker 构建 PaaS 平台的过程中,我们首先遇到的问题是需要选择一个满足需求的网络模型: 让每个容器拥有自己的网络栈,特别是独立的 IP 地址 能够进行跨服务器的容器间通讯,同时不依赖 ...
- SAP R3和JAVA交换数据之JCO
SAP Java Connector (JCo) SAP的JAVA中间件,使用它可以使SAP的客户和合作伙伴使用JAVA语言轻松地建立可以和SAP系统通信的兼容的组件和应用程序下面是JCo一些 ...
- linux下挂载win7的共享文件夹
由于跨平台开发的需要,需要在Linux和windows之间共享文件夹,所以找了一下方法,我试验了两种都可以使用. 首先声明一下我使用的是VMware10.CentOS6.2 一.手动操作 1.按照下图 ...
- github上搭建网站前台页面
其实就是把html页面提交到github,为了能在线演示: 1. 首先在github网站找到你的项目 2. 点击设置 3. 找到这几个选项,选择master branch打钩,然后保存 4. 然后就会 ...
- CSS学习笔记(11)--Flex 布局教程:语法篇
原文--阮一峰博客 作者: 阮一峰 日期: 2015年7月10日 网页布局(layout)是CSS的一个重点应用. 布局的传统解决方案,基于盒状模型,依赖 display属性 + position属性 ...
- Photoshop学习笔记(1)--界面设置
根据慕课网教学视频整理(抄了一个妹子的评论): http://www.imooc.com/video/9813 ps版本:CS6 步骤: 1.视图->显示->智能参考线,以及视图-> ...
- Linux下HTTP Server
想在Linux下实现一个简单的web Server并不难.一个最简单的HTTP Server不过是一个高级的文件服务器,不断地接收客户端(浏览器)发送的HTTP请求,解析请求,处理请求,然后像客户端回 ...