Bound Method and Unbound Method

    通常有两种方法对类的方法(instance.method)/属性(class.attribute)进行引用, 一种称做 Bound Method, 
   即通过类的类的实例对象进行引用(instance.foo)。引用区别于调用, 引用为 instance.foo 返回的是方法对象
   (PyFunctionObject/PyMethodObject); 而调用返回的是方法的运行结果。另一种引用形式叫做 Unboud Method,
   是直接通过类进行属性引用, 即 class.foo 的形式进行引用。 在 python 中, Bound Method 和 Unbound Method 的本质区别在于 是否存在类的 instance 对象绑定到
   PyFunctionObject 中(这里用 '中' 是想说明 PyFunctionObject 是一个结构体,我把它想象成一个容器的形象)。
因此, 在对 Unbound Method 进行调用的时候必须显式地传一个实例对象, 比如 class.UnboundMethod(instance),
   所以说在类中所定义函数的第一个位置参数 self 代表是调用该函数的实例。 然而, 对 python 虚拟机来说, 无论是对
   Bound Method 还是对 Unbound Method 进行调用, 其中本质上是一样的,都是调用带位置参数的普通函数。
其中的区别在于, 当调用 Bound Method 的时候,虚拟机自主完成了 instance 和 PyFunctionObject 的绑定;
   而调用 Unbound Method 的时候虚拟机无法做绑定的动过,因而调用 Unbound Method 的时候需要显式地传入所属类的 instance.
对于通过 Bound Method 调用成员函数来说,每一次函数调用都会触发一次绑定过程。原因在于每次进行引用的时候都会重新获得
   PyFunctionObject(description),进而新的 PyMethodObject 对象。 例子,
 class A(object):
def foo(self):
print "haha - " + self.foo.__name__ print (A.__dict__) # abc = A() print (A.foo) # print(A.foo.im_self) # print (abc.foo) # print (abc.foo.im_self,abc.foo.im_func, #
abc.foo.im_class,abc.foo.__name__) abc.foo() #
try:
print A.foo() #
except TypeError as e:
print e A.foo(abc) #7
通过 dis 模块获取到示例代码的部分字节码,
31 LOAD_NAME 1 (A)
34 LOAD_ATTR 3 (foo)
37 PRINT_ITEM    其中关键在 '34 LOAD_ATTR' 指令一行, LOAD_ATTR 指令最终会调用 type_getattro。
   而 type_getattro 会在 class A 对象的 tp_dict (__dict__ 属性) 中找到 function foo 对应的 PyFunctionObject.
   因为 PyFunctionObject 是一个 descriptor,所以它会调用其 __get__ 函数. 最终,虽然 A.foo(class.foo, Unbound Method)
   也得到了一个 PyMethodObject, 但是其中 im_self 属性却是 None. 示例代码的打印输出,
    Output,
    {... 'foo': <function foo at 0x00000000033A2D68>, '__weakref__': <attribute '__weakref__' of 'A' objects>, ...}  
  #1 type_getattro 会在 class A 对象的 tp_dict (__dict__ 属性) 中找到 function foo 对应的 PyFunctionObject.     <unbound method A.foo> #2 通过类的引用(class.foo) 为 Unbound Method     None #3 虽然 A.foo(class.foo, Unbound Method)也得到了一个 PyMethodObject, 但是其中 im_self 属性却是 None.     <bound method A.foo of <__main__.A object at 0x000000000330AE80>> #4 通过实例的引用(instance.foo) 为 Bound Method     (<__main__.A object at 0x000000000330AE80>, <function foo at 0x00000000033A2D68>, <class '__main__.A'>, 'foo')
      #5 abc.foo(instance.foo, Bound Method)得到的 PyMethodObject 中 im_self 和 im_func 属性分别是 __main__.A 实例对象 和 foo 函数对象.     haha - foo #6 通过实例调用 foo     unbound method foo() must be called with A instance as first argument (got nothing instead) #7 Unbound Method 的调用需要显式地传入实例 instance 对象.
    haha - foo

Bound Method and Unbound Method - 绑定方法 与 非绑定方法的更多相关文章

  1. Day 5-5 绑定方法与非绑定方法

    绑定方法与非绑定方法: 在类内部定义的绑定方法,分两大类: classmehtod是给类用的,即绑定到类,类在使用时会将类本身当做参数传给类方法的第一个参数(即便是对象来调用也会将类当作第一个参数传入 ...

  2. Learning-Python【25】:绑定方法与非绑定方法

    类中定义函数分为了两大类,绑定方法与非绑定方法,它们有一些特殊之处: 1.绑定方法特殊之处:绑定给谁就应该由谁来调用,谁来调用就会将谁当做第一个参数自动传入 绑定给对象的方法:这个在面向对象第一篇第六 ...

  3. Python面向对象之封装、property特性、绑定方法与非绑定方法

    一.封装 ''' 1.什么封装 封:属性对外是隐藏的,但对内是开放的(对内是开放的是因为在类定义阶段这种隐藏已经发生改变) 装:申请一个名称空间,往里装入一系列名字/属性 2.为什么要封装 封装数据属 ...

  4. 全面解析python类的绑定方法与非绑定方法

    类中的方法有两类: 绑定方法 非绑定方法 一.绑定方法 1.对象的绑定方法 首先我们明确一个知识点,凡是类中的方法或函数,默认情况下都是绑定给对象使用的.下面,我们通过实例,来慢慢解析绑定方法的应用. ...

  5. Python开发基础-Day21多态与多态性、绑定方法和非绑定方法

    多态与多态性 多态 多态并不是一个新的知识 多态是指一类事物有多种形态,在类里就是指一个抽象类有多个子类,因而多态的概念依赖于继承 举个栗子:动物有多种形态,人.狗.猫.猪等,python的序列数据类 ...

  6. python基础之多态与多态性、绑定方法和非绑定方法

    多态与多态性 多态 多态并不是一个新的知识 多态是指一类事物有多种形态,在类里就是指一个抽象类有多个子类,因而多态的概念依赖于继承 举个栗子:动物有多种形态,人.狗.猫.猪等,python的序列数据类 ...

  7. Python虚拟机类机制之绑定方法和非绑定方法(七)

    Bound Method和Unbound Method 在Python中,当对作为属性的函数进行引用时,会有两种形式,一种称为Bound Method,这种形式是通过类的实例对象进行属性引用,而另一种 ...

  8. Python--多态与多态性、绑定方法与非绑定方法

    多态与多态性 多态 多态指的是一类事物有多种形态,(一个抽象类有多个子类,因而多态的概念依赖于继承) 1. 序列类型有多种形态:字符串,列表,元组. s='hello' l=[,,] t=('a',' ...

  9. Day7 子类调用父类的方法supper 绑定方法与非绑定方法

    supper:可以利用supper来重用父类的方法,可以不用指名道姓的调用了. class OldboyPeople: school = 'oldboy' def __init__(self,name ...

随机推荐

  1. Numpy常用方法及应用总汇

    目录 Numpy 1.基本操作 1.1数组转换 1.2数组生成 1.3文件读取 1.4查看操作 2.数据类型 2.1指定数据类型: 2.2查看数据类型 2.3数据类型转换 3.数组运算 3.1数组间运 ...

  2. Java 基础(一)| 使用泛型的正确姿势

    前言 为跳槽面试做准备,今天开始进入 Java 基础的复习.希望基础不好的同学看完这篇文章,能掌握泛型,而基础好的同学权当复习,希望看完这篇文章能够起一点你的青涩记忆. 一.什么是泛型 泛型,即&qu ...

  3. Spring学习记录3——Spring AOP

    SpringAOP基础 AOP简介: AOP是Aspect Oriented Programing的简称,翻译为“面向切面编程”.它适用于具有横切逻辑的应用场合,如性能检测,访问控制,事务管理及日志记 ...

  4. php-lnmp环境搭建

    参考网站:http://www.liyblog.top/p/9 1.nginx和php基本安装 1.更新apt apt update 2.安装nginx apt install nginx 3.查看n ...

  5. mysql复习1

    SQL语句分为以下三种类型: DML: Data Manipulation Language 数据操纵语言,用于查询与修改数据记录,包括如下SQL语句:INSERT:添加数据到数据库中UPDATE:修 ...

  6. AVR单片机教程——小结

    本文隶属于AVR单片机教程系列.   第一期挺让我失望的,是我太菜,没有把想讲的都讲出来.经常写了很多,然后一点一点删掉,最后就没多少了. 而且感觉难度不合适,处于很尴尬的位置.讲得简单,难的丢给库, ...

  7. 安装numpy、matplotlib

    一.安装numpy 1.下载 https://pypi.org/project/numpy/#files 2.安装 pip3 install numpy-1.17.3-cp37-cp37m-win_a ...

  8. ORM跨表查询总结

    一.基于对象的查询-->子查询 1.一对多 正向查询:基于 字段 反向查询:基于 表名__set.all() 注意:表名全部小写 2.多对多 正向查询:基于 字段.all() 反向查询:基于 表 ...

  9. Java入门 - 高级教程 - 05.网络编程

    原文地址:http://www.work100.net/training/java-networking.html 更多教程:光束云 - 免费课程 网络编程 序号 文内章节 视频 1 概述 2 Soc ...

  10. Photoshop 2020安装教程

    首先来看看新增功能 [Photoshop 2020新增功能] 1.ipad和云文档 2.预设改进 3.新对象选择工具 4.转换行为一致 5.改进的属性面板 6.智能对到图层 7.增强的转换变形. 需要 ...