对特殊方法的访问 - Special method lookup
对特殊方法的访问 - Special method lookup
对于用户自定义的 class 来说, 特殊方法只有通过定义对象的类型object’s type (而非通过 instance
的 __dict__属性)被定义, 才能保证特殊方法的隐式调用.
也就是说给自定义的 class 打 特殊方法的 monkey patching 后,再通过 conventional'传统方式' 调用是行不通的.
注, conventional'传统方式' 调用 指的是如下面例子中 len() 跟 __len__() 的对应关系.
见下例的 exception,
例,
>>> class C:
... pass
...
>>> c = C()
>>> c.__len__ = lambda: 5
>>> c.__len__()
5
>>> len(c)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: object of type 'C' has no len() 报错的原因在于, 所有对象(包括类型对象) 都有实现特殊方法, 如果通过'传统方式'隐式调用
这些特殊方法(len(c)), 当在类型对象本身上调用对应的特殊方法的时候便会失败.
详见 python doc 中的描述,
The rationale behind this behaviour lies with a number of special methods such as __hash__() and __repr__()
that are implemented by all objects, including type objects.
If the implicit lookup of these methods used the conventional lookup process,
they would fail when invoked on the type object itself: 例如,
>>> 1 .__hash__() == hash(1)
True
>>> int.__hash__() == hash(int)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: descriptor '__hash__' of 'int' object needs an argument 错误在于, 试图去调用一个类(int) 的 unbound method(__hash__), 有时这样的错误调用行为
被称作‘metaclass confusion’. 可以采取通过 instance 访问 special methods
的方式绕过 ‘metaclass confusion’.
>>> type(1).__hash__(1) == hash(1)
True
>>> type(int).__hash__(int) == hash(int)
True 这样做的另外的一个好处是, 对特殊方法的隐式调用同时也绕过 __getattribute__ 方法,
对该对象的的 metaclass 来说也是这样.
>>> class Meta(type):
... def __getattribute__(*args):
... print("Metaclass getattribute invoked")
... return type.__getattribute__(*args)
...
>>> class C(object, metaclass=Meta):
... def __len__(self):
... return 10
... def __getattribute__(*args):
... print("Class getattribute invoked")
... return object.__getattribute__(*args)
...
>>> c = C()
>>> c.__len__() # Explicit lookup via instance
Class getattribute invoked
10
>>> type(c).__len__(c) # Explicit lookup via type
Metaclass getattribute invoked
10
>>> len(c) # Implicit lookup
10 summarize,
'绕过' __getattribute__ 的机制最佳化了解释器的解释速度, 而这种机制是通过对特殊方法的灵活处理
实现的,即特殊方法必须在类对象本身上 set, 而不能通过 monkey patching,再通过 conventional'传统方式' 调用. 注,
conventional'传统方式' 调用 指的是诸如例子中 len() 跟 __len__() 的对应关系. reference,
python doc,
https://docs.python.org/3/reference/datamodel.html#special-lookup
对特殊方法的访问 - Special method lookup的更多相关文章
- action 方法的访问
Action中的方法的访问: 访问Action的中的方法,默认情况下只能访问execute方法.那么多次请求就不能提交到一个Action.能不能一个模块的多次请求提交到一个Action中? * 需要使 ...
- 【译文】 C#面向对象的基本概念 (Basic C# OOP Concept) 第一部分(类,对象,变量,方法,访问修饰符)
译文出处:http://www.codeproject.com/Articles/838365/Basic-Csharp-OOP-Concept 相关文档:http://files.cnblogs.c ...
- .NET设计模式(5):工厂方法模式(Factory Method)(转)
工厂方法模式(Factory Method) ——.NET设计模式系列之五 Terrylee,2004年1月2日 概述 在软件系统中,经常面临着“某个对象”的创建工作,由于需求的变化,这个对象的具体实 ...
- .NET设计模式(5):工厂方法模式(Factory Method)
):工厂方法模式(Factory Method) 工厂方法模式(Factory Method) --.NET设计模式系列之五 Terrylee,2004年1月2日 转载:http://terry ...
- 24种设计模式--模版方法模式【Template Method Pattern】
周三,9:00,我刚刚坐到位置,打开电脑准备开始干活.“小三,小三,叫一下其它同事,到会议室,开会”老大跑过来吼,带着淫笑.还不等大家坐稳,老大就开讲了,“告诉大家一个好消息,昨天终于把牛叉模型公司的 ...
- 工厂方法模式(Factory Method)和抽象工厂模式(Abstact Factory)
分类 工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的.工厂模式在<Java 与模式>中分为三类:1)简单工厂模式(Simple Facto ...
- NET设计模式 第二部分 创建型模式(4):工厂方法模式(Factory Method)
工厂方法模式(Factory Method) ——.NET设计模式系列之五 Terrylee,2004年1月2日 概述 在软件系统中,经常面临着“某个对象”的创建工作,由于需求的变化,这个对象的具体实 ...
- java中,方法可以访问他的类对象的任何私有特性
java中,方法可以访问他的类对象的任何私有特性 读一本书(Core Java for the Impatient)时,发现这个注意,以前的时候没有在意,今天仔细想想发现记忆不深刻.记录一下 下面代码 ...
- [转载]Python方法绑定——Unbound/Bound method object的一些梳理
本篇主要总结Python中绑定方法对象(Bound method object)和未绑定方法对象(Unboud method object)的区别和联系.主要目的是分清楚这两个极容易混淆的概念,顺便将 ...
随机推荐
- Deferred shading rendering path翻译
Overview 概述 When using deferred shading, there is no limit on the number of lights that can affect a ...
- Golang 正则匹配 -- regexp
匹配特殊字符 //re :=regexp.MustCompile("[~!@#$%^&*(){}|<>\\\\/+\\-[]:\"?'::''"&qu ...
- RSA 的加密 解密
RSA加密解密类: package me.hao0.trace.order; import java.io.BufferedReader; import java.io.BufferedWriter; ...
- App的基本结构
今天主要学习安装了Android Studio,并且成功地在虚拟机上运行了HelloWord工程.下面针对HelloWord工程对app的基本框架结构进行一个总结.掌握app的基本结构对初学软件开发的 ...
- python 找到项目使用的所有组件和版本
1.下载模块 pip3 install -i https://pypi.douban.com/simple pipreqs 2.生成文件 pipreqs ./ --encoding=utf-8
- Java入门 - 语言基础 - 20.Stream和File和IO
原文地址:http://www.work100.net/training/java-stream-file-io.html 更多教程:光束云 - 免费课程 Stream和File和IO 序号 文内章节 ...
- 「4.0」一个人开发一个App,小程序从0到1,布局
一提到布局这个词,我总是索索发抖,不是因为天冷,而是因为布局的目标实在太宏大.古代想雄霸天下的王,就喜欢布局这个,布局那个,结果硬生生把自己的国家给布局没了.至于是哪个君王,我倒可以非常认真,非常坦诚 ...
- 从0开发3D引擎(八):准备“搭建引擎雏形”
大家好,现在开始本系列的第三部分,按照以下几个步骤来搭建引擎雏形: 1.分析引擎的需求 2.实现最小的3D程序 3.从中提炼引擎原型 4.一步一步地对引擎进行改进,使其具备良好的架构 5.实现与架构相 ...
- 前端之css的基本使用(一),行内、内部、外部样式,语法格式、注释、选择符、属性等
一.行内.内部.外部样式 1.行内样式 <!DOCTYPE html> <html lang="en"> <head> <meta cha ...
- 《ASP.NET Core 高性能系列》关于性能的闲聊
一.通常的性能问题类型 让我们一起看看那些公共的性能问题,看看他们是或者不是.我们将了解到为什么我们常常在开发期间会错过这些问题.我们也会看看当我们考虑性能时语言的选择.延迟.带宽.计算等因素. 二. ...