python 类的装饰器
我们知道,在不改变原有代码的基础上,我们可以使用装饰器为函数添加新的功能。同理,一切皆对象,我们也可以使用装饰器为类添加类属性。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 类的装饰器的更多相关文章
- 第7.18节 案例详解:Python类中装饰器@staticmethod定义的静态方法
第7.18节 案例详解:Python类中装饰器@staticmethod定义的静态方法 上节介绍了Python中类的静态方法,本节将结合案例详细说明相关内容. 一. 案例说明 本节定义了类Sta ...
- python 类内部装饰器的实现 与 参数解构学习
学习了函数的装饰器的写法,然后想到如果要在类中初始化或获取信息时能用装饰器做过滤和验证应该怎么写呢, 在网上查了下相关信息,感觉这样也是可以的,不知道会不会有什么问题class Ctj(): clas ...
- Python类中装饰器classmethod,staticmethod,property,
@classmethod 有的时候在类中会有一种情况,就是这个方法并不需要使用每一个对象属性 因此 这个方法中的self参数一个完全无用的参数,使用classmethod class A: __cou ...
- python类常用装饰器
class Myclass(object): def __init__(self): pass #必须实例化才能调用 def sayhi(self): print 'hello' #静态方法,跟类没什 ...
- python描述符(descriptor)、属性(property)、函数(类)装饰器(decorator )原理实例详解
1.前言 Python的描述符是接触到Python核心编程中一个比较难以理解的内容,自己在学习的过程中也遇到过很多的疑惑,通过google和阅读源码,现将自己的理解和心得记录下来,也为正在为了该问题 ...
- 11.python描述符---类的装饰器---@property
描述符1.描述符是什么:描述符本质就是一个新式类,在这个新式类中,至少实现了__get__(),__set__(),__delete__()这三个内置方法中的一个,描述符也被称为描述符协议(1):__ ...
- Python之路(第二十八篇) 面向对象进阶:类的装饰器、元类
一.类的装饰器 类作为一个对象,也可以被装饰. 例子 def wrap(obj): print("装饰器-----") obj.x = 1 obj.y = 3 obj.z = 5 ...
- 详解Python闭包,装饰器及类装饰器
在项目开发中,总会遇到在原代码的基础上添加额外的功能模块,原有的代码也许是很久以前所写,为了添加新功能的代码块,您一般还得重新熟悉源代码,稍微搞清楚一点它的逻辑,这无疑是一件特别头疼的事情.今天我们介 ...
- 面向切面编程AOP——加锁、cache、logging、trace、同步等这些较通用的操作,如果都写一个类,则每个用到这些功能的类使用多继承非常难看,AOP就是解决这个问题的,python AOP就是装饰器
面向切面编程(AOP)是一种编程思想,与OOP并不矛盾,只是它们的关注点相同.面向对象的目的在于抽象和管理,而面向切面的目的在于解耦和复用. 举两个大家都接触过的AOP的例子: 1)java中myba ...
随机推荐
- bzoj 4898: [Apio2017]商旅【Floyd+分数规划+二分】
其实并不会分数规划 因为要最大化 ans=总收益/总路程 ,所以考虑二分答案,找到一条 ans<=总收益/总路程 的回路.先预处理出d(i,j)为(i,j)最短路,w(i,j)为在i买某个物品在 ...
- Ubuntu 18 安装 wps
本来有三种方法 1. 软件中心 安装最简单 2. 命令行snap 安装 如果没有安装snap 先安装 sudo apt install snapd 然后安装wps sudo snap install ...
- python之对堆栈、队列处理操作(转载+个人看法)
参考链接:https://blog.csdn.net/u010786109/article/details/40649827 python实现堆栈操作 堆栈是一个后进先出的数据结构,其工作方式就像一堆 ...
- java String, StringBuffer ,StringBulider 区别
1. String 是不可变的(immutable): 创建后不能修改: 2. StringBuffer 线程安全的,可变字符串: 3. StringBuilder 线程不安全,所以性能比较高
- 第二个Struts2程序 应用动态Action
1.创建web项目,添加struts2支持的类库,在web.xml中配置struts2过滤器. 2.创建名为UserAction的Action对象,并分别在其中编写add()和update()方法,用 ...
- ORA-14074: partition bound must collate higher than that of the last partition
There is a error happen in crotab: CREATE parttion report ORA-14074:ORA-14074: partition bound must ...
- Windows 7操作系统下Apache的安装与配置(图文详解)
我这里是 Apache2.4.X-win64 首先, 我的操作系统信息如下 Apache2.4-win64的下载 官网 http://www.apachelounge.com/download/ 因 ...
- Ref 和 Out 区别(演练代码)
一.代码 今天就总结Ref和Out 的总结,这东西,也是经常面试过程中,笔试经常考的,比如:请简述Ref和Out 的区别,或者通过一段代码让你计算这过程的结果.... Out代码实例::: stati ...
- AJPFX关于通过索引获取最大值的思路
/*** 通过索引获取最大值***/public class Test1 { public static void main(String[] args) { ...
- 免费大数据搜索引擎 xunsearch 实践
以前在IBM做后端开发时,也接触过关于缓存技术,当时给了n多文档来学习,后面由于其他紧急的项目,一直没有着手去仔细研究这个技术,即时后来做Commerce的时候,后台用了n多缓存技术,需要build ...