python元类为类的全部方法添加装饰器

2024-01-23 09:52

本文主要是介绍python元类为类的全部方法添加装饰器,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1 python元类为类的全部方法添加装饰器

装饰器和元类都在class语句的末尾运行,同时使用装饰器和元类实现对一个类的所有方法应用一个函数装饰器。

1.1 调用次数和计时函数

示例

>>> import time,sys
>>> def tracer(func):calls=0def onCall(*args,**kargs):nonlocal callscalls+=1print('调用 %s %s 次' % (func.__name__,calls))return func(*args,**kargs)return onCall>>> def timer(label='',trace=True):def onDecorator(func):def onCall(*args,**kargs):beg=time.perf_counter()res=func(*args,**kargs)usetime=time.perf_counter()-begonCall.alltime+=usetimeif trace:timestr='{0[0]}:usetime={0[1]:.6f},alltime={0[2]:.6f}'timeval=func.__name__,usetime,onCall.alltimeprint(label,timestr.format(timeval))return resonCall.alltime=0return onCallreturn onDecorator

1.2 用装饰器手动统计调用次数

描述

在需要统计调用次数和计时的每个方法前手动编写@装饰语法。

示例

>>> class Staff:@tracerdef __init__(self,name,pay):self.name=nameself.pay=pay@tracerdef giveRaise(self,rate):self.pay*=(1.0+rate)@tracerdef lastName(self):return self.name[0]>>> s1=Staff('张三',50000)
调用 __init__ 1>>> s2=Staff('李四',51000)
调用 __init__ 2>>> print(s1.name,s2.name)
张三 李四
>>> s1.giveRaise(0.1)
调用 giveRaise 1>>> s1.pay
55000.00000000001
>>> print(s1.lastName(),s2.lastName())
调用 lastName 1 次
调用 lastName 2 次
张 李

1.3 用元类和装饰器统计调用次数

描述

手动使用装饰器使用于需装饰方法数量较少的情况。如果需对一个类的全部方法进行装饰,则通过元类将装饰器添加到每个方法中,达到自动装饰的效果。

示例

>>> from types import FunctionType
>>> class MetaTrace(type):def __new__(meta,classname,supers,classdict):for attr,attrval in classdict.items():# 类属性为方法则自动装饰if type(attrval) is FunctionType:# 调用装饰器 trace 重新绑定装饰方法classdict[attr]=tracer(attrval)return type.__new__(meta,classname,supers,classdict)>>> class Staff(metaclass=MetaTrace):def __init__(self,name,pay):self.name=nameself.pay=paydef giveRaise(self,rate):self.pay*=(1.0+rate)def lastName(self):return self.name[0]>>> s1=Staff('张三',50000)
调用 __init__ 1>>> s2=Staff('李四',51000)
调用 __init__ 2>>> print(s1.name,s2.name)
张三 李四
>>> s1.giveRaise(0.1)
调用 giveRaise 1>>> s1.pay
55000.00000000001
>>> print(s1.lastName(),s2.lastName())
调用 lastName 1 次
调用 lastName 2 次
张 李

1.4 把任何装饰器应用于方法

描述

通过元类把传入的装饰器应用到一个类的所有方法,只需在原来外层定义一个函数接收传入队装饰器即可。

示例

>>> from types import FunctionType
>>> def decoratorAll(decorator):class MetaTrace(type):def __new__(meta,classname,supers,classdict):for attr,attrval in classdict.items():if type(attrval) is FunctionType:classdict[attr]=decorator(attrval)return type.__new__(meta,classname,supers,classdict)return MetaTrace
>>> class Staff(metaclass=decoratorAll(tracer)):def __init__(self,name,pay):self.name=nameself.pay=paydef giveRaise(self,rate):self.pay*=(1.0+rate)def lastName(self):return self.name[0]>>> s1=Staff('张三',50000)
调用 __init__ 1>>> s2=Staff('李四',51000)
调用 __init__ 2>>> print(s1.name,s2.name)
张三 李四
>>> s1.giveRaise(0.1)
调用 giveRaise 1>>> s1.pay
55000.00000000001
>>> print(s1.lastName(),s2.lastName())
调用 lastName 1 次
调用 lastName 2 次
张 李
# 使用timer装饰器
>>> class Staff(metaclass=decoratorAll(timer(label='**'))):def __init__(self,name,pay):self.name=nameself.pay=paydef giveRaise(self,rate):self.pay*=(1.0+rate)def lastName(self):return self.name[0]>>> s1=Staff('张三',50000)
** __init__:usetime=0.000003,alltime=0.000003
>>> s2=Staff('李四',51000)
** __init__:usetime=0.000002,alltime=0.000004
>>> print(s1.name,s2.name)
张三 李四
>>> s1.giveRaise(0.1)
** giveRaise:usetime=0.000009,alltime=0.000009
>>> s1.pay
55000.00000000001
>>> print(s1.lastName(),s2.lastName())
** lastName:usetime=0.000002,alltime=0.000002
** lastName:usetime=0.000004,alltime=0.000006
张 李

这篇关于python元类为类的全部方法添加装饰器的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/636025

相关文章

问题:第一次世界大战的起止时间是 #其他#学习方法#微信

问题:第一次世界大战的起止时间是 A.1913 ~1918 年 B.1913 ~1918 年 C.1914 ~1918 年 D.1914 ~1919 年 参考答案如图所示

[word] word设置上标快捷键 #学习方法#其他#媒体

word设置上标快捷键 办公中,少不了使用word,这个是大家必备的软件,今天给大家分享word设置上标快捷键,希望在办公中能帮到您! 1、添加上标 在录入一些公式,或者是化学产品时,需要添加上标内容,按下快捷键Ctrl+shift++就能将需要的内容设置为上标符号。 word设置上标快捷键的方法就是以上内容了,需要的小伙伴都可以试一试呢!

大学湖北中医药大学法医学试题及答案,分享几个实用搜题和学习工具 #微信#学习方法#职场发展

今天分享拥有拍照搜题、文字搜题、语音搜题、多重搜题等搜题模式,可以快速查找问题解析,加深对题目答案的理解。 1.快练题 这是一个网站 找题的网站海量题库,在线搜题,快速刷题~为您提供百万优质题库,直接搜索题库名称,支持多种刷题模式:顺序练习、语音听题、本地搜题、顺序阅读、模拟考试、组卷考试、赶快下载吧! 2.彩虹搜题 这是个老公众号了 支持手写输入,截图搜题,详细步骤,解题必备

电脑不小心删除的文件怎么恢复?4个必备恢复方法!

“刚刚在对电脑里的某些垃圾文件进行清理时,我一不小心误删了比较重要的数据。这些误删的数据还有机会恢复吗?希望大家帮帮我,非常感谢!” 在这个数字化飞速发展的时代,电脑早已成为我们日常生活和工作中不可或缺的一部分。然而,就像生活中的小插曲一样,有时我们可能会在不经意间犯下一些小错误,比如不小心删除了重要的文件。 当那份文件消失在眼前,仿佛被时间吞噬,我们不禁会心生焦虑。但别担心,就像每个问题

Python 字符串占位

在Python中,可以使用字符串的格式化方法来实现字符串的占位。常见的方法有百分号操作符 % 以及 str.format() 方法 百分号操作符 % name = "张三"age = 20message = "我叫%s,今年%d岁。" % (name, age)print(message) # 我叫张三,今年20岁。 str.format() 方法 name = "张三"age

一道经典Python程序样例带你飞速掌握Python的字典和列表

Python中的列表(list)和字典(dict)是两种常用的数据结构,它们在数据组织和存储方面有很大的不同。 列表(List) 列表是Python中的一种有序集合,可以随时添加和删除其中的元素。列表中的元素可以是任何数据类型,包括数字、字符串、其他列表等。列表使用方括号[]表示,元素之间用逗号,分隔。 定义和使用 # 定义一个列表 fruits = ['apple', 'banana

Python应用开发——30天学习Streamlit Python包进行APP的构建(9)

st.area_chart 显示区域图。 这是围绕 st.altair_chart 的语法糖。主要区别在于该命令使用数据自身的列和指数来计算图表的 Altair 规格。因此,在许多 "只需绘制此图 "的情况下,该命令更易于使用,但可定制性较差。 如果 st.area_chart 无法正确猜测数据规格,请尝试使用 st.altair_chart 指定所需的图表。 Function signa

python实现最简单循环神经网络(RNNs)

Recurrent Neural Networks(RNNs) 的模型: 上图中红色部分是输入向量。文本、单词、数据都是输入,在网络里都以向量的形式进行表示。 绿色部分是隐藏向量。是加工处理过程。 蓝色部分是输出向量。 python代码表示如下: rnn = RNN()y = rnn.step(x) # x为输入向量,y为输出向量 RNNs神经网络由神经元组成, python

python 喷泉码

因为要完成毕业设计,毕业设计做的是数据分发与传输的东西。在网络中数据容易丢失,所以我用fountain code做所发送数据包的数据恢复。fountain code属于有限域编码的一部分,有很广泛的应用。 我们日常生活中使用的二维码,就用到foutain code做数据恢复。你遮住二维码的四分之一,用手机的相机也照样能识别。你遮住的四分之一就相当于丢失的数据包。 为了实现并理解foutain

flask 中使用 装饰器

因为要完成毕业设计,我用到fountain code做数据恢复。 于是在github上下载了fountain code的python原代码。 github上的作者用flask做了fountain code的demo。 flask是面向python的一个网站框架。 里面有用到装饰器。 今天笔试的时候,我也被问到了python的装饰器。