[Python] First-class Everything (Python缔造者Guido van Rossum关于bound/unbound method的来历叙述)
First-class Everything
-- Guido van Rossum
First-class object: 第一类对象。意指可在执行期创建并作为参数传递给其他函数或存入一个变量的对象。 简而言之,第一类对象在使用时没有任何限制。第一类对象典型特征是可以动态创建、销毁,作为参数传递,可以作为返回值,具有一个变量的所具有的所有特性。
我关于Python的一个发展目标就是所有的对象都是第一类对象。鉴于此,我希望Python中的所有已命名的对象都具有相同的状态。也就是说,所有对象都可以赋值给变量,可以放进列表中,保存在字典里,作为参数传递等等。
Python的实现原理让这个目标变得简单。所有Python的对象都基于一个相同的C语言数据结构,这种结构充斥着Python解释器。变量、列表、函数等所有东西都使用这个数据结构的变体。这个数据结构与它要呈现的对象类型无关,无论是简单如整数,复杂如类都一样。
尽管实现第一类对象看起来简单,但我还是需要去面对类的一个微妙的地方——也就是,影响让method对象成为第一类对象的因素。
试看一个简单的Python类:
class A:
def __init__(self, x):
self.x = x
def spam(self, y):
print self.x, y
如果method对象成为第一类对象,那么它们就可以像其他Python对象一样被分配给变量。比如,某人可以写一条Python语句"s = A.spam"。此时,变量"s"指向一个类的方法,这个方法其实是个函数。但是,方法和普通的函数不同。方法的第一个参数应该是该定义了该方法的那个类的实例。
为解决这个问题,我创造了一种可调用对象"unbound method"。一个未绑定方法其实就是对实现该方法的函数的封装,它强制要求了它接收的第一个参数必须是定义了该方法的类的实例。因此,如果有人想像函数那样调用未绑定方法"s",他们只能将class A的一个实例作为第一个参数传递给"s"。就像"a = A(); s(a)"[注1]。
但随之带来一个问题,如果有人写了一条语句引用某个对象实例上的一个方法。比如,某人创建了一个实例"a = A()",然后写了另一条语句"s = a.spam"。此时,变量"s"再次指向一个类的方法,但是要引用这个方法需要通过instance对象"a"。为解决这个问题,另一个可调用对象"bound method"就派上用场了。这个对象也是对函数对象进行了一层简单封装。但是,这个封装对象隐式地保存了用来获取method的instance对象。因此,在执行"s()"时会隐式地将使用实例"a"作为第一个参数去调用目标方法。
实际上,bound和unbound方法都是使用同一种内部类型来呈现。该类型的对象有一个属性包含了指向某个实例的索引。如果该索引为None,那么它表示的就是unbound method,否则bound method。
尽管bound和unbound可能看起来不是很重要的小细节,但它们在Python类中却是很至关重要的一部分。每当在程序中执行"a.spam()"时,它的执行过程其实分为两部分。首先,查找"a.spam",这个过程结束后返回一个bound method——一个可调用对象;然后,对该对象使用函数调用符"()",从而使用用户提供的参数对方法进行调用。
[注1]在Python 3000中,unbound method的概念已去除,表达式"A.spam"返回一个函数对象。事实证明,对第一个参数必须是A的实例的限制对诊断问题几乎毫无帮助,对一些高级用法反而常常是个障碍。所谓高级用法可以理解为鸭子型态。
[Python] First-class Everything (Python缔造者Guido van Rossum关于bound/unbound method的来历叙述)的更多相关文章
- [Python] 当猎头遇上 Guido van Rossum
Guido van Rossum 收到猎头的邀请函和他的回复. 猎头 你好,Guido! 我在 Google 搜索中无意间看见你的简历.看起来你精通 Python.我非常愉快能够得到你的回复并了解你的 ...
- [Python] Python 之 function, unbound method 和 bound method
首先看一下以下示例.(Python 2.7) #!/usr/bin/env python # -*- coding: utf-8 -*- class C(object): def foo(self): ...
- 我的Python学习之路 Python的初识与准备工作
注:文笔不好,不喜勿喷,当个段子看看就好 一.初识Python 第一次听到Python是在2016年大概暑假 时候(即将大三),因为对黑客技术的蜜汁热爱(虽然自己并不会),在玄魂大大的公众微信号中看到 ...
- Python之路(一)-python简介
一.python简介,python2.x与python3.x的区别 Python是著名的“龟叔”Guido van Rossum在1989年圣诞节期间,为了打发无聊的圣诞节而编写的一个编程语言. Py ...
- JavaScript之父Brendan Eich,Clojure 创建者Rich Hickey,Python创建者Van Rossum等编程大牛对程序员的职业建议
软件开发是现时很火的职业.据美国劳动局发布的一项统计数据显示,从2014年至2024年,美国就业市场对开发人员的需求量将增长17%,而这个增长率比起所有职业的平均需求量高出了7%.很多人年轻人会选择编 ...
- python学习笔记(python简史)
一.python介绍 python的创始人为吉多·范罗苏姆(Guido van Rossum) 目前python主要应用领域: ·云计算 ·WEB开发 ·科学运算.人工智能 ·系统运维 ·金融:量化交 ...
- python基础之初始python
初始python之基础一 一.Python 介绍 1.python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发 ...
- Python学习第一弹——Python环境搭建
一.Python简介: Python,是一种面向对象.解释型计算机程序设计语言,由Guido van Rossum于1989年底发明,第一个公开发行版发行于1991年.Python语法简洁而清晰,具有 ...
- 进击的Python【第一章】:Python背景初探与Python基础(一)
Python背景初探 一.Python起源 Python的创始人为Guido van Rossum.1989年圣诞节期间,在阿姆斯特丹,Guido为了打发圣诞节的无趣,决心开发一个新的脚本解释程序,做 ...
随机推荐
- 路由策略和策略路由 & route-map
今天,这个专题应用下route-map,在这个之前,有很多内容需要掌握,不是简单的制定一个路由图就可以了. -------- 本次专题理论的东西居多,但是不是复制黏贴,是加上自己的理解思想. 第一个要 ...
- android学习中遇到的错误
1.运行项目的时候报错: [2013-12-16 17:59:22 - Dex Loader] Unable to execute dex: java.nio.BufferOverflowExcept ...
- SpringBoot系列三:SpringBoot基本概念(统一父 pom 管理、SpringBoot 代码测试、启动注解分析、配置访问路径、使用内置对象、项目打包发布)
声明:本文来源于MLDN培训视频的课堂笔记,写在这里只是为了方便查阅. 1.了解SpringBoot的基本概念 2.具体内容 在之前所建立的 SpringBoot 项目只是根据官方文档实现的一个基础程 ...
- WCF Service 配置文件注释(转)
VS 2008 SP1(不确定是否不打SP1是否有)自带的一个编辑工具,可以更快的帮助定制配置文件, 以前看到过没有注意, 昨天正好一个同事提起, 这里记录一笔:打开VS 2008->Tools ...
- Git -- 分支管理简介
分支就是科幻电影里面的平行宇宙,当你正在电脑前努力学习Git的时候,另一个你正在另一个平行宇宙里努力学习SVN. 如果两个平行宇宙互不干扰,那对现在的你也没啥影响.不过,在某个时间点,两个平行宇宙合并 ...
- 回想sql语句中的各种连接
1. 内连接(Inner Join) 内连接是最常见的一种连接,它页被称为普通连接,而E.FCodd最早称之为自然连接. 以下是ANSI SQL-92标准 select * from t_ins ...
- Linux环境安装MySQL数据库(RPM格式的软件包)
1. 下载mysql安装包 下载地址1: http://www.mysql.com/ (mysql官网) 下载地址2: http://mirrors.sohu.com/mysql/ (其 ...
- winform 用户控件事件的写法
public partial class UcTest : UserControl { public UcTest() { InitializeComponent(); } //定义事件 public ...
- Castle.Windsor依赖注入的高级应用_Castle.Windsor.3.1.0
[转]Castle.Windsor依赖注入的高级应用_Castle.Windsor.3.1.0 1. 使用代码方式进行组件注册[依赖服务类] using System; using System.Co ...
- 精心挑选的HTML5/CSS3应用及源码
这段时间我已经为大家分享了不少关于HTML5应用和jQuery插件了,先来回顾一下: 炫酷霸气的HTML5/jQuery应用及源码 干货分享 超炫丽的HTML5/jQuery应用及代码 绚丽而实用的j ...