Python Cookbook-6.6 在代理中托管特殊方法
任务
在新风格对象模型中,Python 操作其实是在类中查找特殊方法的(而不是在实例中那是经典对象模型的处理方式)。现在,需要将一些新风格的实例包装到代理类中,此代理可以选择将一些特殊方法委托给内部的被包装对象。
解决方案
你需要即时地生成各个代理类。如下,
class Proxy(object):"""所有代理的基类"""def __init__(self,obj):super(Proxy,self).__init__(obj)self.obj = objdef __getattr__(self,attrib):return getattr(self._obj,attrib)
def make_binder(unbound_method):def f(self,*a,**k): return unbound_method(self._obj, *a,**k)#仅2.4:f.__name__ = unbound_method.__name__return f
known_proxy_classes = { }
def proxy(obj,*specials):'''能够委托特殊方法的代理的工厂函数'''#我们手上有合适的自定义的类吗?obj_cls = obj.__class__key = obj_cls, specialscls = known_proxy_classes.get(key)if cls is None:#我们手上没有合适的类,那就现做一个cls = type("%sProxy" %obj_cls.__name__, (Proxy,){})for name in specials:name = '__%s__' %nameunbound_method = getattr(obj_cls,name)setattr(cls,name,make_binder(unbound_method))#缓存之以供进一步使用known_proxy_classes[key] = cls#实例化并返回需要的代理return cls(obj)
讨论
代理和自动托管都是 Python 中的玩具,这得归功于__getattr__的机制。在查询任何属性时(包括方法,Python并不区分两者),Python都会自动调用__getattr__。
在旧风格(经典)对象模型中,__getattr__同样适用于特殊方法,这些方法常常被认为是 Python 操作的一部分。在使用中也需要当心错误地提供一个我们不想提供的特殊方法。而现在,在新代码中使用新风格的对象模型成为推荐方式:速度更快,更符合规定,特性也更丰富。当你从 object或任何内建类型派生子类时就得到了新风格的类。也许几年后的某一天,Python3.0将彻底地剔除经典对象模型以及其他一些仅仅是为了保证向后兼容的特性。(参看 http://www.python.org/peps/pep-3000.html 提供的关于Python 3.0 的计划细节,几乎都是以简化语言为主,而不是新增功能。)
在新风格对象模型中,Python 操作并不会在运行时查找特殊方法:它们依赖于类对象的“槽”(slots)。这些槽会在类对象被创建或者修改时更新。因此,对于一个代理对象,如果它要把特殊方法托管给被封装的对象,它本身必须属于某个量身定做的类。幸好如同解决方案的代码所示,在 Python中,凭空创造并实例化类是一件很简单的事情。
在本节,我们不使用任何高级的 Python 概念,比如自定义元类和描述符。事实上,每个代理都是由一个工厂函数 proxy 创建的,该函数接受一个封装的对象以及要托管的特殊方法的名字作为参数(除去前面和后面的两个下划线符号)。如果你把解决方案中的代码存为一个文件 proxy.py并放入你的 Python的 sys.path 中,就可以用下面的方法在 Python 解释器中使用它:
>>> import proxy
>>>a = proxy.proxy([],'len','iter')#只托管len和iter
>>> a#__repr__未被托管
<proxy.listProxy object at 0x0113C370>
>>> a.__class__
<elass 'proxy.listProxy'>
>>>a._obj
[ ]
>>>a.append#所有的非特殊方法都被托管了
<built-in method append of list object at 0x010F1A10>
由于__len__被托管了,于是len(a)像预期那样工作:
>>> len(a)
0
>>> a.append(23)
>>>len(a)
1
由于__iter__被托管了,for 循环也如同预期那样工作,和通过内建的list、sum、max等操作执行的循环一样:
>>>for x in a:print x
...
23
>>> list(a)
[23]
>>>sum(a)
23
>>> max(a)
23
不过,由于__getitem__没有被托管,a无法进行索引或切片操作:
>>> a.__getitem__
<method-wrapper object at0x010F1AF0>
>>> a[1]
Traceback (most recent call last):File "<interactive input>",line l, in ?
TypeError:unindexable obiect
函数 proxy 使用的是以前创建的类的“缓存”,即全局字典 known_proxy_classes,它以被封装的对象的类和被托管的特殊方法的名字为键。如果要生成一个新类,proxy 就调用内建的 type,将新类的名字作为一个参数传入(在被包装的对象的类名后加了个“Proxy”),类 Proxy 作为唯一的基类,是一个“空”的类字典(它还没有加入任何属性)。基类 Proxy 进行初始化处理和对普通属性的查询的托管。然后,工厂函数 proxy 循环处理被托管的特殊方法名:对每一个名字,它都从被封装对象的类获得未绑定方法,并将其作为一个属性赋给闭包make binder中的新类。当遇到对这些未绑定方法的调用时,make_binder会提供一个适合的参数(比如被封装对象本身,self.obj)。
一旦完成了新类的准备,proxy将其存入known_proxy_classes,并以适当的键标记之最后,无论类是被创建或者从known_proxy_classes中获取的,proxy 都会使用被封装对象作为唯一参数,将其实例化,然后返回最后的代理实例。
相关文章:
Python Cookbook-6.6 在代理中托管特殊方法
任务 在新风格对象模型中,Python 操作其实是在类中查找特殊方法的(而不是在实例中那是经典对象模型的处理方式)。现在,需要将一些新风格的实例包装到代理类中,此代理可以选择将一些特殊方法委托给内部的被包装对象。 解决方案 你需要即时地…...
PCIE Spec ---Base Address Registers
7.5.1.2.1 Base Address Registers (Offset 10h - 24h) 在 boot 到操作系统之前,系统软件需要生产一个内存映射的 address map ,用于告诉系统有多少内存资源,以及相应功能需要的内存空间,所以在设备的 PCI 内存空间中就有了这个 …...
Spring如何通过XML注册Bean
在上一篇当中我们完成了对三种资源文件的读写 上篇内容:Spring是如何实现资源文件的加载 Test public void testClassPathResource() throws IOException { DefaultResourceLoader defaultResourceLoader new DefaultResourceLoader(); Resource resource …...
理解 `#pragma pack`:C/C++内存对齐的钥匙
引言:为什么我的网络程序收发的数据总是错位? 在网络编程中,你是否遇到过这样的困惑:明明发送方和接收方的结构体定义完全一样,但解析出来的数据却乱七八糟?这很可能是因为内存对齐在作祟。今天我们就来深…...
开源键鼠共享软件的“爱恨情仇“:Deskflow、InputLeap与Barrier的演化史
开源键鼠共享软件的"爱恨情仇":Deskflow、InputLeap与Barrier的演化史 一、血脉渊源:从Synergy到三足鼎立 这三款软件的起源都与 Synergy 这款商业软件密切相关: 2001年:Synergy开创软件化KVM先河2017年&…...
【Python核心库实战指南】从数据处理到Web开发
目录 前言:技术背景与价值当前技术痛点解决方案概述目标读者说明 一、技术原理剖析核心概念图解核心作用讲解关键技术模块对比 二、实战演示环境配置要求核心代码实现(5个案例)案例1:NumPy数组运算案例2:Pandas数据分析…...
运维:概念、模式与硬件基础
一、运维概述:从网管到智能运维的进化之路 1. 运维岗位的定义 IT运维管理是保障企业IT系统及网络可用性、安全性、稳定性,确保业务连续性的核心工作。通过专业技术手段,对计算机网络、应用系统、电信网络、软硬件环境及运维服务流程等进行综…...
基于Java的不固定长度字符集在指定宽度和自适应模型下图片绘制生成实战
目录 前言 一、需求介绍 1、指定宽度生成 2、指定列自适应生成 二、Java生成实现 1、公共方法 2、指定宽度生成 3、指定列自适应生成 三、总结 前言 在当今数字化与信息化飞速发展的时代,图像的生成与处理技术正日益成为众多领域关注的焦点。从创意设计到数…...
【版本控制】idea中使用git
大家好,我是jstart千语。接下来继续对git的内容进行讲解。也是在开发中最常使用,最重要的部分,在idea中操作git。目录在右侧哦。 如果需要git命令的详解: 【版本控制】git命令使用大全-CSDN博客 一、配置git 要先关闭项目…...
QT:Qt5 串口模块 (QSerialPort) 在 VS2015 中正确关闭串口避免被占用
以下是使用 Qt5 串口模块 (QSerialPort) 在 VS2015 中正确关闭串口避免被占用的完整示例代码: #include <QSerialPort> #include <QDebug>// 创建全局或类成员变量(推荐使用智能指针) QSerialPort *serialPort nullptr; // 打开…...
Linux——入门常用基础指令
文章目录 Linux入门常用基础指令使用工具介绍基础指令clear指令pwd指令ls指令cd指令Linux系统下的文件路径及文件存储结构文件结构家目录绝对路径和相对路径tree工具 stat指令which指令alias指令touch指令mkdir指令cat指令rm指令man指令cp指令通配符 * Linux入门常用基础指令 …...
【技术追踪】Differential Transformer(ICLR-2025)
Differential Transformer:大语言模型新架构, 提出了 differential attention mechanism,Transformer 又多了一个小 trick~ 论文:Differential Transformer 代码:https://github.com/microsoft/unilm/tree/master/Diff…...
overlay 模块加载失败问题分析
问题背景 CentOS 7系统上,内核版本是3.10.0-693.21.1.el7.x86_64,加载overlay模块的时候失败了。错误提示说找不到支持的overlay文件系统,让我确认内核足够新并且已经加载了overlay支持。但是检查发现/lib/modules/3.10.0-693.el7.x86_64/ke…...
【Linux网络】应用层自定义协议与序列化
🌈个人主页:秦jh__https://blog.csdn.net/qinjh_?spm1010.2135.3001.5343 🔥 系列专栏:https://blog.csdn.net/qinjh_/category_12891150.html 目录 应用层 再谈 "协议" 网络版计算器 序列化 和 反序列化 重新理解…...
Vue接口平台学习十——接口用例页面2
效果图及简单说明 左边选择用例,右侧就显示该用例的详细信息。 使用el-collapse折叠组件,将请求到的用例详情数据展示到页面中。 所有数据内容,绑定到caseData中 // 页面绑定的用例编辑数据 const caseData reactive({title: "",…...
目标检测中的损失函数(二) | BIoU RIoU α-IoU
BIoU来自发表在2018年CVPR上的文章:《Improving Object Localization With Fitness NMS and Bounded IoU Loss》 论文针对现有目标检测方法只关注“足够好”的定位,而非“最优”的框,提出了一种考虑定位质量的NMS策略和BIoU loss。 这里不赘…...
SpringAI系列 - MCP篇(一) - 什么是MCP
目录 一、引言二、MCP核心架构三、MCP传输层(stdio / sse)四、MCP能力协商机制(Capability Negotiation)五、MCP Client相关能力(Roots / Sampling)六、MCP Server相关能力(Prompts / Resources / Tools)一、引言 之前我们在接入大模型时,不同的大模型通常都有自己的…...
Linux 入门十一:Linux 网络编程
一、概述 1. 网络编程基础 网络编程是通过网络应用编程接口(API)编写程序,实现不同主机上进程间的信息交互。它解决的核心问题是:如何让不同主机上的程序进行通信。 2. 网络模型:从 OSI 到 TCP/IP OSI 七层模型&…...
沐渥氮气柜控制板温湿度氧含量氮气流量四显智控系统
氮气柜控制板通常用于实时监控和调节柜内环境参数,确保存储物品如电子元件、精密仪器、化学品等,处于低氧、干燥的稳定状态。以下是沐渥氮气柜控制板核心参数的详细介绍及控制逻辑: 一、控制板核心参数显示模块 1)温度显示&am…...
vue3 主题模式 结合 element-plus的主题
vue3 主题模式 结合 element-plus的主题 npm i element-plus --save-dev在 Vue 3 中,实现主题模式主要有以下几种方式 1.使用 CSS 变量(自定义属性) CSS 变量是一种在 CSS 中定义可重用值的方式。在主题模式中,可以将颜色、字体…...
Redis 有序集合(Sorted Set)
Redis 有序集合(Sorted Set) 以下从基础命令、内部编码和使用场景三个维度对 Redis 有序集合进行详细解析: 一、基础命令 命令时间复杂度命令含义zadd key score member [score member …] O ( k l o g ( n ) ) O(klog(n)) O(klog(n))&…...
[c语言日寄]免费文档生成器——Doxygen在c语言程序中的使用
【作者主页】siy2333 【专栏介绍】⌈c语言日寄⌋:这是一个专注于C语言刷题的专栏,精选题目,搭配详细题解、拓展算法。从基础语法到复杂算法,题目涉及的知识点全面覆盖,助力你系统提升。无论你是初学者,还是…...
QtCreator的设计器、预览功能能看到程序图标,编译运行后图标消失
重新更换虚拟机(Vmware Kylin),重新编译和配置了很多第三方库后,将代码跑到新的这个虚拟机环境中,但是出现程序图标不可见,占位也消失,后来继续检查ui文件,ui文件图标也异常&#x…...
QT文件和文件夹拷贝操作
1.拷贝文件夹 //(源文件目录路劲,目的文件目录,文件存在是否覆盖) bool copyDirectory(const QString& srcPath, const QString& dstPath, bool coverFileIfExist) { QDir srcDir(srcPath); QDir dstDir(dstPath); if (!dstDir.exi…...
面试常用基础算法
目录 快速排序归并排序堆排序 n n n皇后问题最大和子数组爬楼梯中心扩展法求最长回文子序列分割回文串动态规划求最长回文子序列最长回文子串单调栈双指针算法修改 分割回文串滑动窗口栈 快速排序 #include <iostream> #include <algorithm>using namespace std;…...
Python-24:小R的随机播放顺序
问题描述 小R有一个特殊的随机播放规则。他首先播放歌单中的第一首歌,播放后将其从歌单中移除。如果歌单中还有歌曲,则会将当前第一首歌移到最后一首。这个过程会一直重复,直到歌单中没有任何歌曲。 例如,给定歌单 [5, 3, 2, 1,…...
悬空引用和之道、之禅-《分析模式》漫谈57
DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 “Analysis Patterns”的第5章“对象引用”原文: Unless you can catch all such references, there is the risk of a dangling reference, which often has painful con…...
Python accumulate 函数详解
https://docs.python.org/zh-cn/3/library/itertools.html#itertools.accumulate 在 Python 中,accumulate 是一个生成器(generator), 是来自 itertools 模块的一个函数。 它的作用是返回一个迭代器,该迭代器生成输入数据的累积结…...
Cursor可视化大屏搭建__0420
主题:用Cursor怎么进行数据洞察,做AI预测化内容。 Python基础语法与AI python生态强大,代码简洁,相对其他语言Python更好上手,浙江高考将Python列为可选科目 科学计算:Sklearn,Numpy,Pandas 人工智能:Tensorflow,Pytorch 网络爬虫:Scrapy…...
【初阶数据结构】树——二叉树(上)
文章目录 目录 前言 一、树 1.树的概念与结构 2.树相关术语 3.树的表示 二、二叉树 1.概念与结构 2.特殊的二叉树 3.二叉树存储结构 总结 前言 本篇带大家学习一种非线性数据结构——树,简单认识树和二叉数以及了解二叉树的存储结构。 一、树 1.树的概念与结构 树…...
