绑定和方法调用
现在我们需要再次阐述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. struts2--上传总结(限制大小和类型 非法上传的跳转)

    网上有很多版本,鉴于实践出真知的态度 我自己探索了一番 struts版本:2.3.16 限制大小: struts2默认是2M 所以如果要扩大大小限制,应该先配一个全局struts2最大上限 <c ...

  2. (工具类)MD5算法|时间格式转换|字符串转数字

    package vote.utils; import java.security.MessageDigest; import java.text.SimpleDateFormat; import ja ...

  3. matlab 图像Mat类型矩阵中的值(uint8)类型转换,防止溢出

    a=[50,60,70; 80,90,50; 100,55,40] 假设a是一个灰度图的mat形式(当然实际的size肯定比这大,我只是举例子),如果需要对这个矩阵的像素进行加减处理,很可能会产生溢出 ...

  4. [讲解]sql except和intersect运算符(比拟两个或多个select语句的结果并前去非重复值)

    图 1 UNION 中若有重复的行,会被移除,只留下一个 1.简介 EXCEPT和INTERSECT运算符使您可以比较两个或多个SELECT语句的结果并返回非重复值. 2.区别 EXCEPT运算符返回 ...

  5. 点击除指定元素以外的任意地方隐藏js

    $(document).click(function () { $(".search_box").hide(); }); $(".resultUl").on(& ...

  6. 【Python】Python 猜年龄的游戏

    游戏规则: 允许用户最多尝试3次 每尝试3次后,如果还没猜对,就问用户是否还想继续玩,如果回答Y或y, 就继续让其猜3次,以此往复,如果回答N或n,就退出程序 如何猜对了,就直接退出 age= cou ...

  7. Collections带有的排序方法 传入的元素类型 需是子类或者这个类的实例

  8. 【BZOJ2763】飞行路线(最短路)

    [BZOJ2763]飞行路线(最短路) 题面 BZOJ Description Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公司一共在n个城市设有业务,设这些城市分别标 ...

  9. SCWS中文分词,功能函数实例应用

    结合前文的demo演示,现写一个实用的功能函数,使用方法:header('Content-Type:text/html;charset=UTF-8');$text        = '我是一个中国人, ...

  10. SMBv3空指针引用dos漏洞复现

    0x01 前言 去年年底,当设置一个模拟器来定位SMB协议时,发现了一个如此简单而又非常有效的攻击大型企业的漏洞.TL; DR:一个拒绝服务错误允许BSOD协议向Windows 8.1和Windows ...