- 译者序
- 前言
- 第1章 问答环节
- 第2章 Python 如何运行程序
- 第3章 如何运行程序
- 第4章 介绍 Python 对象类型
- 第5章 数字
- 第6章 动态类型简介
- 第7章 字符串
- 第8章 列表与字典
- 第9章 元组、文件及其他
- 第10章 Python 语句简介
- 第11章 赋值、表达式和打印
- 第12章 if 测试和语法规则
- 第13章 while 和 for 循环
- 第14章 迭代器和解析,第一部分
- 第15章 文档
- 第16章 函数基础
- 第17章 作用域
- 第18章 参数
- 第19章 函数的高级话题
- 第20章 迭代和解析,第二部分
- 第21章 模块:宏伟蓝图
- 第22章 模块代码编写基础
- 第23章 模块包
- 第24章 高级模块话题
- 第25章 OOP:宏伟蓝图
- 第27章 更多实例
- 第28章 类代码编写细节
- 第29章 运算符重载
- 第30章 类的设计
- 第31章 类的高级主题
- 第32章 异常基础
- 第34章 异常对象
- 第35章 异常的设计
- 第36章 Unicode 和字节字符串
- 字符串基础知识
- Python 的字符串类型
- 文本和二进制文件
- Python 3.0 中的字符串应用
- 转换
- 编码 Unicode 字符串
- 编码非ASCII文本
- 编码和解码非ASCII文本
- 其他 Unicode 编码技术
- 转换编码
- 在 Python 2.6 中编码 Unicode 字符串
- 源文件字符集编码声明
- 使用 Python 3.0 Bytes 对象
- 序列操作
- 创建 bytes 对象的其他方式
- 混合字符串类型
- 使用 Python 3.0(和 Python 2.6)bytearray 对象
- 使用文本文件和二进制文件
- Python 3.0 中的文本和二进制模式
- 类型和内容错误匹配
- 使用 Unicode 文件
- 在 Python 3.0 中处理 BOM
- Python 2.6 中的 Unicode 文件
- Python 3.0 中其他字符串工具的变化
- Struct二进制数据模块
- pickle对象序列化模块
- XML解析工具
- 本章小结
- 本章习题
- 习题解答
- 第37章 管理属性
- 第38章 装饰器
- 第39章 元类
- 附录A 安装和配置
- 附录B 各部分练习题的解答
- 作者介绍
- 封面介绍
Call表达式:__call__
更正式地说,我们在第18章介绍的所有参数传递方式,__call__方法都支持——传递给实例的任何内容都会传递给该方法,包括通常隐式的实例参数。例如,方法定义:
都匹配如下所有的实例调用:
直接的效果是,带有一个__call__的类和实例,支持与常规函数和方法完全相同的参数语法和语义。
像这样的拦截调用表达式允许类实例模拟类似函数的外观,但是,也在调用中保持了状态信息以供使用(我们在本书第17章中介绍作用域的时候看到过一个类似的示例,但是,在这里,你应该对运算符重载更熟悉):
在这个示例中,__call__乍一看可能有点奇怪。一个简单的方法可以提供类似的功能:
然而,当需要为函数的API编写接口时,__call__就变得很有用:这可以编写遵循所需要的函数来调用接口对象,同时又能保留状态信息。事实上,这可能是除了__init__构造函数以及__str__和__repr__显示格式方法外,第三个最常用的运算符重载方法了。
函数接口和回调代码
作为例子,tkinter GUI工具箱(在Python 2.6中是Tkinter)可以把函数注册成事件处理器(也就是回调函数callback)。当事件发生时,tkinter会调用已注册的对象。如果想让事件处理器保存事件之间的状态,可以注册类的绑定方法(bound method)或者遵循所需接口的实例(使用__call__)。在这一节的代码中,第二个例子中的x.comp和第一个例子中的x都可以用这种方式作为类似于函数的对象进行传递。
下一章会再介绍绑定方法,这里仅举一个假设的__call__例子,应用于GUI领域。下列类定义了一个对象,支持函数调用接口,但是也有状态信息,可记住稍后按下按钮后应该变成什么颜色。
现在,在GUI环境中,即使这个GUI期待的事件处理器是无参数的简单函数,我们还是可以为按钮把这个类的实例注册成事件处理器。
当这个按钮按下时,会把实例对象当成简单的函数来调用,就像下面的调用一样。不过,因它把状态保留成实例的属性,所以知道应该做什么。
实际上,这可能是Python语言中保留状态信息的最好方式,比之前针对函数所讨论的技术更好(全局变量、嵌套函数作用域引用以及默认可变参数等)。利用OOP,状态的记忆是明确地使用属性赋值运算而实现的。
在继续之前,Python程序员偶尔还会用两种其他方式,把信息和回调函数联系起来。其中一个选项是使用lambda函数的默认参数:
另一种是使用类的绑定方法:这种对象记住了self实例以及所引用的函数,使其可以在稍后通过简单的函数调用而不需要实例来实现。
当按钮按下时,就好像是GUI这么做的,启用changeColor方法来处理对象的状态信息:
这种技巧较为简单,但是比起__call__重载调用而言就不通用了;同样,有关绑定方法可参考下一章的内容。
在第31章你会看到另一个__call__例子,我们会通过它来实现所谓的函数装饰器的概念:它是可调用对象,在嵌入的函数上多加一层逻辑。因为__call__可让我们把状态信息附加在可调用对象上,所以自然而然地成为了被一个函数记住并调用了另一函数的实现技术。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论