绑定和方法调用
现在我们需要再次阐述Python中绑定(binding)的概念,它主要与方法调用相关联。
方法是类内部定义的函数,这意味着方法是类属性而不是实例属性。
其次,方法只有在其所属的类拥有实例时,才能被调用。当存在一个实例时,方法才被认为是绑定到那个实例了,没有实例时,方法就是未绑定的。
任何一个方法定义中都有一个参数是变量self。它表示调用此方法的实例对象。

核心笔记:
self变量用于在类实例方法中引用方法所绑定的实例。方法的实例在任何方法调用中总是作为第一参数传递的,self代表方法的实例。你必须在方法声明中放上self,如果你的方法中没有用到self,那么考虑创建一个常规函数,除非有特殊的原因。毕竟,方法代码中没有使用实例,没有与类关联其功能,这使它看起来像一个常规函数。

调用绑定方法
一个实例可以调用绑定的方法,调用时,不需要明确地传入self了,只需要传入其他参数,这是因为我们遵循了声明时self必须作为第一参数的一个报酬。

调用非绑定方法
调用非绑定方法并不经常用到。这种方法的主要场景是:你在派生一个子类,而且你要覆盖父类的方法,这是你需要调用那个父类中想要覆盖掉的构造方法。

class EmplAddrBookEntry(AddrBookEntry):
  'Employee Address Book Entry Class'
  def __init__ (self, nm, ph, ph)
    AddrBookEntry.__init__(self, nm, ph)
    self.empid = id
    self.email = em

我们重构了子类的构造器,但想尽可能多地重用代码而不是复制粘贴代码,所以调用了父类的构造器。
当一个EmplAddrBookEntry被实例化后,调用__init__(),虽然我们没有AddrBookEntry的实例,但依然可以调用这样的方法。
这就是调用非绑定方法的最佳地方了。我们在子类构造器中调用父类构造器并且明确地传递父类构造器所需要的self参数。子类中__init__()的第一行就是对父类__init__()的调用。我们通过父类名来调用它,一旦调用返回,我们再定义那些仅在子类中使用的定制。

静态方法和类方法
静态方法仅是类中的函数(不需要实例),通常的方法需要一个实例(self)作为第一个参数,对于绑定的方法调用来说,self是自动传递给这个方法的。而对于类方法而言,需要类而不是实例作为第一个参数,它是由解释器传给方法,类不需要特别地命名,类似self,不过很多人使用cls作为变量名字。

staticmethod()和classmethod()内建函数
我们来创建一下静态方法和类方法:

>>> class TestStaticMethod(object):
  def foo():
    print 'calling static method foo()' >>>
>>> a = TestStaticMethod()
>>> a.foo() Traceback (most recent call last):
File "<pyshell#15>", line 1, in <module>
a.foo()
TypeError: foo() takes no arguments (1 given)

当我们调用这个方法时,解释器出现错误,显示需要带self的常规方法声明。那应该如何做呢?

>>> class TestStaticMethod:
  def foo():
    print 'calling static method foo()'
  foo = staticmethod(foo) >>> a = TestStaticMethod()
>>> a.foo()
calling static method foo()
>>> TestStaticMethod.foo()
calling static method foo()

我们用了staticmethod()内建函数,就能正常通过类或者实例访问这个方法。
同理,类方法需要这样定义:

>>> class TestClassMethod(object):
  def foo(cls):
    print 'calling class method foo()'
    print 'foo() is part of class:', cls.__name__
  foo = classmethod(foo) >>> TestClassMethod.foo()
calling class method foo()
foo() is part of class: TestClassMethod
>>> b = TestClassMethod()
>>> b.foo()
calling class method foo()
foo() is part of class: TestClassMethod

这里用了cls作为类方法的第一个参数,当然这不是必须的。

使用函数修饰符
看到像foo=staticmethod(foo)这样的无意义的语法会让人心烦。它只是临时的,有待社区对这些语义进行处理。
我们可以把函数修饰符用到这个函数对象上,用它来整理语法。如上面的,我们可以使用这样写防止重新赋值:

class TestStaticMethod(object):
  @staticmethod
  def foo():
    print 'calling static method foo()' class TestClassMethod(object):
  @classmethod
  def foo(cls):
    print 'calling class method foo()'
    print 'foo() is part of class:', cls.__name__

2015/9/21 Python基础(17):绑定和方法调用的更多相关文章

  1. Python基础:绑定和方法调用

    首先,方法仅仅是类内部定义的函数,也就是说,方法是类属性而不是实例属性. 其次方法有两种被调用的方式:调用绑定的方法和调用未绑定的方法. 当存在一个实例时,方法才被认为绑定到了那个实例上,没有实例时方 ...

  2. 二十一. Python基础(21)--Python基础(21)

    二十一. Python基础(21)--Python基础(21) 1 ● 类的命名空间 #对于类的静态属性:     #类.属性: 调用的就是类中的属性     #对象.属性: 先从自己的内存空间里找名 ...

  3. 十七. Python基础(17)--正则表达式

    十七. Python基础(17)--正则表达式 1 ● 正则表达式 定义: Regular expressions are sets of symbols that you can use to cr ...

  4. Python基础------列表,元组的调用方法

    Python基础------列表,元组的调用方法@@@ 一. 列表 Python中的列表和歌曲列表类似,也是由一系列的按特定顺序排列的元素组成的,在内容上,可以将整数,实数,字符串,列表,元组等任何类 ...

  5. 2015/10/9 Python基础(21):可调用和可执行对象

    在Python中有多种运行外部程序的方法,比如,运行操作系统命令或另外的Python脚本,或执行一个磁盘上的文件,或通过网络来运行文件.这完全取决于想要干什么.特定的环境包括: 在当前脚本继续运行 创 ...

  6. 2015/9/20 Python基础(16):类和实例

    面向对象编程编程的发展已经从简单控制流中按步的指令序列进入到更有组织的方式中,依靠代码块可以形成命名子程序和完成既定的功能.结构化的或过程性编程可以让我们把程序组织成逻辑快,以便重复或重用.创造程序的 ...

  7. 2015/9/22 Python基础(18):组合、派生和继承

    一个类被定义后,目标就是把它当成一个模块来使用,并把这些对象嵌入到你的代码中去,同其他数据类型及逻辑执行流混合使用.有两种方法可以在你的代码中利用类.第一种是组合,就是让不同的类混合并加入到其他类中, ...

  8. 2015/9/29 Python基础(20):类的授权

    类的授权 1.包装包装在Python编程世界中时经常会被提到的一个术语.它是一个通用的名字,意思是对一个已存在的对象进行包装,不管它是数据类型,还是一段代码,可以是对一个已存在的对象,增加新的,删除不 ...

  9. 2015/9/28 Python基础(19):类的定制和私有性

    用特殊方法定制类前面我们讲了方法的两个重要方面:首先,方法必须在调用前被绑定(到它们相应类的某个实例中):其次,有两个特殊方法可以分别作为构造器和解构器的功能,分别名为__init__()和__del ...

随机推荐

  1. ios程序后台继续运行

    1.图标右上角显示消息个数 if ([[UIDevice currentDevice].systemVersion doubleValue] >= 8.0) { UIUserNotificati ...

  2. ViewController 视图控制器的常用方法

    ViewController 视图控制器 ,是控制界面的控制器,通俗的来说,就是管理我们界面的大boss,视图控制器里面包含了视图,下面举个例子,让视图在两个视图上调转. 定义一个视图控制器: MyV ...

  3. Matlab中TCP通讯-实现外部程序提供优化目标函数解

    版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:Matlab中TCP通讯-实现外部程序提供优化目标函数解     本文地址:http://te ...

  4. PHP内置标准类

    PHP内置标准类 php语言内部,有“很多现成的类”,其中有一个,被称为“内置标准类”. 这个类“内部”可以认为什么都没有,类似这样: class  stdclass{ } 其作用,可以用于存储一些临 ...

  5. Css实现拖动效果

    效果如下,可以拖动滑块,数字显示的是离左侧距离:

  6. hive表信息查询:查看表结构、表操作等--转

    原文地址:http://www.aboutyun.com/forum.PHP?mod=viewthread&tid=8590&highlight=Hive 问题导读:1.如何查看hiv ...

  7. BZOJ 2462 矩阵模板(二维hash)

    题意:给出一个n*m的01矩阵,以及k个a*b的01矩阵,问每个是否能匹配原来的01矩阵. 由于k个矩阵的长和宽都是一样的,所以把原矩阵的所有a*b的子矩阵给hash出来.然后依次查找是否存在即可. ...

  8. BZOJ 2424 订货(贪心+单调队列)

    怎么题解都是用费用流做的啊...用单调队列多优美啊. 题意:某公司估计市场在第i个月对某产品的需求量为Ui,已知在第i月该产品的订货单价为di,上个月月底未销完的单位产品要付存贮费用m,假定第一月月初 ...

  9. 【HDU4689】Derangement(动态规划)

    [HDU4689]Derangement(动态规划) 题面 Vjudge 给定一个\(+-\)组成的字符串,长度为\(n\). 如果第\(i\)位是\(+\),那么\(p_i>i\),否则\(p ...

  10. Linux内核分析第六周学习笔记——分析Linux内核创建一个新进程的过程

    Linux内核分析第六周学习笔记--分析Linux内核创建一个新进程的过程 zl + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/U ...