[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为了打发圣诞节的无趣,决心开发一个新的脚本解释程序,做 ...
随机推荐
- Writing a Reusable Custom Control in WPF
In my previous post, I have already defined how you can inherit from an existing control and define ...
- 《FPGA全程进阶---实战演练》第十二章 二进制码与格雷码PK
大家在写程序的时候,可能会听闻,什么独热码,什么格雷码,什么二进制码等等,本节意在解释这几种编码之间的区别和优势以及用verilog怎么去实现,下面先介绍这几种编码的区别. 1 基础理论部分 1.1 ...
- c++11 std::move() 的使用
std::move函数可以以非常简单的方式将左值引用转换为右值引用.(左值.左值引用.右值.右值引用 参见:http://www.cnblogs.com/SZxiaochun/p/8017475.ht ...
- Java如何使用线程解决死锁?
在Java编程中,如何使用线程解决死锁? 以下示例演示如何使用线程的概念解决死锁问题. // from W w w .Y I I b AI.c o M package com.yiibai; impo ...
- (转)Live555单线程原理
1. 概述 在live555-Server库中,使用单线程实现了多用户请求视频数据,这似乎多线程才能实现的功能,并且用户请求视频数据各个流程衔接的都十分完美,其执行效率非常高. live555是如何实 ...
- update-alternatives常用命令(转自http://blog.csdn.net/baggio1006/article/details/6338623)
Linux 发展到今天,可用的软件已经非常多了.这样自然会有一些软件的功能大致上相同.例如,同样是编辑器,就有 nvi.vim.emacs.nano,而且我说的这些还只是一部分.大多数情况下,这样的功 ...
- EXP无法导出空表的表结构解决办法
原文链接:http://www.cnblogs.com/Mr_JinRui/archive/2012/11/05/2755035.html 早的一次使用oracle 11g导出数据发现有的表丢失了,感 ...
- LCL Socket基类
SocketBase类库主要是方便创建Socket客户端和Socket服务端的基础实现. 抽象基类:主要实现创建Socket public abstract class NetworkBase{} 通 ...
- ping失败的结果分析
①Request timed out 这是大家经常碰到的提示信息,很多文章中说这是对方机器置了过滤ICMP数据包,从上面工作过程来看,这是不完全正确的,至少有下几种情况. a. 对方已关机,或者网络上 ...
- Java常用类(二)String类详解
前言 在我们开发中经常会用到很多的常用的工具类,这里做一个总结.他们有很多的方法都是我们经常要用到的.所以我们一定要把它好好的掌握起来! 一.String简介 1.1.String(字符串常量)概述 ...