[关闭]
@hpp157 2016-08-14T13:53:20.000000Z 字数 1522 阅读 1952

Python设计模式——Methods Are Objects: Bound or Unbound

方法也是一种对象,不管是有界方法还是无界方法

Python


有界方法
是一个用于表示 有界方法 (bound methods) 的内部对象。方法的特殊之处在于它还带有一个所在对象的引用。

通常,Python中的方法特别是有界方法,简化了很多设计目标的实现。我们在第三十章介绍__call__的时候简单介绍了有界方法,完备的讲解会在这里给出,比你期望的还要通用和灵活。
在第十九章中,我们学习了函数是如何可以看作常规对象来处理的。methods也是一种对象并且可以用处理常规对象的手段来处理methods——可以把它们赋值给变量名,传递给一个函数,存储在数据结构中等等,就像一个简单的函数,有资格成为“一等对象”,虽然类方法可以通过实例或者类来访问,但是实际上在Python中有两种形式 。

Unbound(class)method对象:无self

通过对类进行点号运算从而获取累得函数属性,会返回无绑定的方法对象。调用该方法时,你必须明确提供实例对象为第一个参数,在Python3.X中,一个无绑定方法和一个简单的函数一模一样,可以通过类名来调用;

绑定实例(instance)方法对象:self + 一组函数(function pairs)

通过对类进行全运算获取类的函数属性时,会返回一个绑定的方法对象,Python在绑定方法对象中自动把实例和函数打包,所以不用传入实例去调用该方法(会自动把self换成实例)

这两种方法都是功能齐全的对象,可以四处传递,就像字符串和数字。两者都需要它们在第一参数中的实例(也就是self)的值。这也是为什么我们在上一章在子类方法调用超类方法是,要刻意的传入实例。从严格意义来讲,这类调用会产生无绑定的方法对象

调用bound methods(也就是instance method)时,Python会自动提供实例——实例常用来创建bound method 对象。意思就是,bound method 对象常常可以和简单函数对象互换,这让原本为函数而编写接口时变得特别有用(参看后面的方框“为什么要在意:绑定方法和毁掉函数”部分中的例子
为了解释清楚,假设我们定义下面的类:

class Spam:
    def doit(self,message):
        print(message)

现在,在正常操作中,创建了一个实例,在单步中调用了它的方法,从而打印出传入的参数:

object1 = Spam()
object1.doit('hello, world')

不过,其实,一个bound method对象是单步调用这个过程中产生的,就在方法调用的括号前边。事实上,我们可以不实际调用就获取绑定方法。在下面代码中,会传回bound method对象,把实例和方法函数(Span.doit)打包起来。我们可以把这个bound method pair赋值给另一个变量名,然后像简单函数那样进行调用。

object1  = Spam()
x=object1.doit  #Bound method object:instance +function
x('hello world')  #same effect as object.doic('hello world')

另一方面,如果对进行点号运算来获得doit,就会得到unbound method 对象,也就函数对象的简单引用。要调用这类方法,必须传入实例作为最左侧参数。

object1 = Spam()
t = Spam.doit      #unbound method object
t(object1,'howdy')  #pass instance

在python 3.X中也可以不传入实例,这样的话,这样的方法被当作简单函数对待,

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注