Python装饰器重载内置操作

1 Python装饰器重载内置操作

python2.x的新式类和python3.x的全部类,内置操作表达式调用,不会触发__getattr__()和__getattribute__()。参考《python的getattr和getattribute拦截内置操作》。

NO内置操作表达式(隐式调用)对应方法(显式调用)
1索引操作[i]__getitem__
2加法(连接)操作+__coerce__ __add__
3括号调用()__call__
4打印print()__str__

__coerce__:表示强制类型转换,使用加法(或连接)操作+时,不同类型会触发类型转换或者报错。

内置操作调用方式:隐式调用,即调用表达式;显式调用,即调用方法名。

1.1 Py3内置操作表达式调用无法委托

描述

内置操作的表达式调用,无法在python3.0下委托,因为不会触发__getattr__()和__getattribute__()。

示例

>>> def traceCall(*args):#跟踪调用if trace:print('['+','.join(map(str,args))+']')>>> def accessCtrl(forbid):def onDecorator(aCls):class onInstance:def __init__(self,*args,**kargs):self.__wrapped=aCls(*args,**kargs)def __getattr__(self,attr):traceCall('getattr',attr)if forbid(attr):raise TypeError('禁止访问:'+attr)else:return getattr(self.__wrapped,attr)def __setattr__(self,attr,value):traceCall('setattr',attr,value)# 压缩后的变量名为 _onInstance__wrappedif attr=='_onInstance__wrapped':self.__dict__[attr]=valueelif forbid(attr):raise TypeError('禁止设置:'+attr)else:setattr(self.__wrapped,attr,value)return onInstancereturn onDecorator>>> def privateAttr(*privates):return accessCtrl(forbid=(lambda attr:attr in privates))>>> @privateAttr('phone')
class Staff_Private:def __init__(self,name,phone):self.name=nameself.phone=phonedef __str__(self):return 'Staff_Private->手机号:'+str(self.phone)def __add__(self,num):self.phone+=num

Python2.x执行

Py2的__getattr__()拦截print()和+等内置操作的表达式调用,正确的委托给装饰对象。

#python2.x执行
>>> trace=True
>>> sp1=Staff_Private('梯阅线条',110)
[setattr,_onInstance__wrapped,Staff_Private->手机号:110]
#py2传统类 拦截内置操作表达式调用-隐式调用,print()
>>> print(sp1)
[getattr,__str__]
Staff_Private->手机号:110
#py2传统类 拦截内置操作表达式调用-隐式调用,+
>>> sp1+1
[getattr,__coerce__]
[getattr,__add__]
>>> print(sp1)
[getattr,__str__]
Staff_Private->手机号:111

Python3.x执行

Py3的__getattr__()不拦截print()和+等内置操作的表达式调用,无法委托给装饰对象。

#python3.x执行
>>> trace=True
>>> sp1=Staff_Private('梯阅线条',110)
[setattr,_onInstance__wrapped,Staff_Private->手机号:110]
#py3没有拦截内置操作 print
>>> print(sp1)
<__main__.accessCtrl.<locals>.onDecorator.<locals>.onInstance object at 0x0000019736C2F4F0>
#py3没有拦截内置操作 + 
>>> sp1+1
Traceback (most recent call last):File "<pyshell#11>", line 1, in <module>sp1+1
TypeError: unsupported operand type(s) for +: 'onInstance' and 'int'

1.2 装饰器重载内置操作

描述

Python3.x的装饰器重载内置操作运算符方法,来拦截装饰类对应的内置表达式调用。

比如,重载__str__()拦截print(),__add__()拦截+。

示例

>>> def traceCall(*args):#跟踪调用if trace:print('['+','.join(map(str,args))+']')
>>> def accessCtrl(forbid):def onDecorator(aCls):class onInstance:def __init__(self,*args,**kargs):self.__wrapped=aCls(*args,**kargs)def __getattr__(self,attr):traceCall('getattr',attr)if forbid(attr):raise TypeError('禁止访问:'+attr)else:return getattr(self.__wrapped,attr)def __setattr__(self,attr,value):traceCall('setattr',attr,value)# 压缩后的变量名为 _onInstance__wrappedif attr=='_onInstance__wrapped':self.__dict__[attr]=valueelif forbid(attr):raise TypeError('禁止设置:'+attr)else:setattr(self.__wrapped,attr,value)# print()触发__str__()def __str__(self):traceCall('onInstance,__str__')# str()触发__str__()return str(self.__wrapped)# + 触发 __add__()    def __add__(self,other):traceCall('onInstance,__add__',other)return self.__wrapped+otherreturn onInstancereturn onDecorator>>> def privateAttr(*privates):return accessCtrl(forbid=(lambda attr:attr in privates))>>> @privateAttr('phone')
class Staff_Private:def __init__(self,name,phone):self.name=nameself.phone=phonedef __str__(self):traceCall('Staff_Private,__str__')return 'Staff_Private->手机号:'+str(self.phone)def __add__(self,num):traceCall('Staff_Private,__add__',num)self.phone+=num>>> trace=True
>>> sp1=Staff_Private('梯阅线条',110)
[Staff_Private,__str__]#traceCall调用print()触发__str__()
[setattr,_onInstance__wrapped,Staff_Private->手机号:110]
# print()触发__str__()
>>> print(sp1)
[onInstance,__str__]
[Staff_Private,__str__]
Staff_Private->手机号:110
# + 触发 __add__()
>>> sp1+1
[onInstance,__add__,1]
[Staff_Private,__add__,1]
>>> print(sp1)
[onInstance,__str__]
[Staff_Private,__str__]
Staff_Private->手机号:111

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/625426.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深度学习记录--Train/dev/test sets

为什么需要训练集、验证集(简单交叉验证集)和测试集&#xff1f; 为了创建高效的神经网络&#xff0c;需要不断进行训练(迭代) 一个神经网络的产生 从最开始的想法idea开始&#xff0c;然后付诸于代码code&#xff0c;根据结果验证反过来对一开始的想法idea进行修正&#xf…

一、引言(DataWhale大模型理论基础)

引言 一、什么是语言模型 语言模型&#xff08;LM&#xff1a;language model&#xff09; 定义&#xff1a;一种对令牌序列(token)的概率分布 说明&#xff1a; 假设我们有一个令牌集的词汇表 V 。语言模型p为每个令牌序列 x1, …,xL ∈ V 分配一个概率&#xff08;介于0和…

腾讯云服务器怎么买?两种购买方式更省钱

腾讯云服务器购买流程很简单&#xff0c;有两种购买方式&#xff0c;直接在官方活动上购买比较划算&#xff0c;在云服务器CVM或轻量应用服务器页面自定义购买价格比较贵&#xff0c;但是自定义购买云服务器CPU内存带宽配置选择范围广&#xff0c;活动上购买只能选择固定的活动…

深度系统QT 环境搭建

1.QT安装 不折腾最新版直接去商店搜索QT安装。 2.修改su密码&#xff0c;安装需要权限 打开一个终端&#xff0c;然后输入下面的命令&#xff1a;按照提示输入密码按回车就行。 sudo passwd 回车后会出现让你输入现在这个账户的密码&#xff1a; 3.编译环境安装。 安…

JUC-线程中断机制和LockSupport

线程中断机制 概念 java提供了一种用于停止线程的协商机制-中断。称为中断标识协商机制。 常用API public void interrupt() 仅仅让线程的中断标志位设置为true。不进行其他操作。public boolean isInterrupted() 获取中断标志位的状态。public static boolean interrupted…

案例分享:销售管理者和员工的一对一面谈

销售面谈对于销售过程至关重要&#xff0c;在快速变化的市场环境中&#xff0c;一对一的面谈成为销售管理者与销售员工之间沟通的重要桥梁。 通过这种沟通方式&#xff0c;双方可以共同探讨销售工作的各个方面&#xff0c;包括业绩回顾、目标设定、技能提升、市场变化应对以及…

CSS实现超出部分的省略

1、为什么要省略 在日常开发过程中我们难免会遇到后端返回给我们的的数据太长的情况&#xff0c;此时我们通常采取的是...的省略方式&#xff0c;其中的CSS大致如下&#xff0c;既可以实现对应的省略显示&#xff0c;但有些时候我们有需要用户可以查看具体的完整信息&#xff0…

利用Python的csv(CSV)库读取csv文件并取出某个单元格的内容的学习过程

csv库在python3中是自带的。 利用它可以方便的进行csv文件内容的读取。 注意&#xff1a;要以gbk的编码形式打开&#xff0c;因为WPS的csv文件默认是gbk编码&#xff0c;而不是utf-8。 01-读取表头并在打印每一行内容时一并输出表头 表头为第1行&#xff0c;现在要读取并打…

基础面试题整理4

1.mybatis的#{}和${}区别 #{}是预编译处理&#xff0c;${}是字符串替换#{}可以防止SQL注入&#xff0c;提高安全性 2.mybatis隔离级别 读未提交 READ UNCOMMITED&#xff1a;读到了其他事务中未提交的数据&#xff0c;造成"脏读","不可重复读","幻读&…

1月12日1月15日代码随想录路经总和从中序和后序遍历构造二叉树

112.路经总和 给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径&#xff0c;这条路径上所有节点值相加等于目标和 targetSum 。如果存在&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 叶子节点 …

局部替换 阿里 ReplaceAnything

目录 阿里的ReplaceAnything,没开源, 可以人体替换、服装替换、物体替换以及背景替换等等。

matlab|基于VMD-SSA-LSTM的多维时序光伏功率预测

目录 1 主要内容 变分模态分解(VMD) 麻雀搜索算法SSA 长短期记忆网络LSTM 2 部分代码 3 程序结果 4 下载链接 1 主要内容 之前分享了预测的程序基于LSTM的负荷和可再生能源出力预测【核心部分复现】&#xff0c;该程序预测效果比较好&#xff0c;并且结构比较清晰&#…

【打卡】牛客网:BM91 反转字符串

自己写的&#xff1a; 直接使用reverse()函数。 class Solution { public:/*** 代码中的类名、方法名、参数名已经指定&#xff0c;请勿修改&#xff0c;直接返回方法规定的值即可** 反转字符串* param str string字符串 * return string字符串*/string solve(string str) {/…

buuctf-Misc 题目解答分解118-120

118.[INSHack2017]sanity 打开压缩包就是一个md 文件 typora 打开 发现flag INSA{Youre_sane_Good_for_you} 119.粽子的来历 解压压缩包 &#xff0c;得到文件夹如下 用010 editor 打开 我是A.doc 这个有些可以 都改成FF 保存 然后再次打开 docx 文件就发现了屈原的诗 其他b…

uniapp + node.js 开发问卷调查小程序

前后端效果图 后端&#xff1a;nodejs 12.8 ; mongoDB 4.0 前端&#xff1a;uniapp 开发工具&#xff1a;HBuilderX 3.99 前端首页代码 index.vue <!-- 源码下载地址 https://pan.baidu.com/s/1AVB71AjEX06wpc4wbcV_tQ?pwdl9zp --><template><view class&q…

新年送长辈礼物怎么选?华为畅享70 Pro 给长辈的新年贴心机

随着春节的脚步越来越近&#xff0c;我们也在为如何表达对长辈的关爱而烦恼。新年送礼&#xff0c;不仅要表达心意&#xff0c;更要考虑到长辈的需求和习惯。今天&#xff0c;我为大家带来一款特别适合长辈的礼物——华为畅享70 Pro。 首先&#xff0c;最直观的感受就是“大”。…

【学习笔记】[AGC043F] Jewelry Box

点击看题意 Part 1 前置知识&#xff1a; L P LP LP对偶费用流。 考虑这样一个费用流&#xff1a;每条边 u v uv uv的流量设为 f u v f_{uv} fuv​&#xff0c;容量设为 c u v c_{uv} cuv​&#xff0c;费用设为 w u v w_{uv} wuv​。 b u b_u bu​设为流出-流入。要求 m i …

工具一本通--Jmeter

工具安装 安装程序包 运行Jmeter.bat 语言设置成中文 1 临时修改&#xff1a;Options > Choose Language > Chinese(Simplified) 2 永久修改&#xff1a;./bin/jmeter.properties #Preferred GUI language. Comment out to use the JVM default locale’s language. #la…

Docker部署Traefik结合内网穿透远程访问Dashboard界面

文章目录 前言1. Docker 部署 Trfɪk2. 本地访问traefik测试3. Linux 安装cpolar4. 配置Traefik公网访问地址5. 公网远程访问Traefik6. 固定Traefik公网地址 前言 Trfɪk 是一个云原生的新型的 HTTP 反向代理、负载均衡软件&#xff0c;能轻易的部署微服务。它支持多种后端 (D…

手机视频转换gif怎么操作?一个小妙招教你手机在线制gif

在现代社会gif动图已经是一种非常流行的图片格式了。可以通过视频转换gif的方式将自己的想法和创意制作成gif动图与好友进行分享斗图。那么&#xff0c;当我们想要在手机上完成视频转换成gif动图是应该怎么办呢&#xff1f;通过使用手机端的gif动图制作&#xff08;https://www…