注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

旷世的忧伤

不与夏虫语寒,不与曲人语道,因为生命缺乏言说的条件......

 
 
 

日志

 
 

Python中未绑定的类方法与绑定的类方法以及super函数  

2014-11-01 23:30:25|  分类: Python语言 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
在python中,访问类的方法可以通过实例也可以通过类来直接访问。Python中的类方法也是一种对象。通过类直接访问的方法称为“未绑定的方法”,而通过实例访问的方法称为“绑定的方法”:

1. 未绑定的类方法:没有self
    通过类来引用方法返回一个未绑定方法对象。要调用它,你必须显示地提供一个实例作为第一个参数。

2. 绑定的实例方法:有self
    通过实例访问方法返回一个绑定的方法对象。Python自动地给方法绑定一个实例,所以我们调用它时不用再传一个实例参数。

两种方法都是对象,它们可以被传递、存入列表等待。两者运行时都需要一个实例作为第一参数,但当通过一个实例调用一个绑定方法时Python自动会提供一个。例:

class Test:
def func(self,message):
print message

object1=Test()
x=object1.func
x('绑定方法对象,实例是隐含的')

t=Test.func
t(object1,'未绑定的方法对象,需要传递一个实例')

#t('未绑定的方法对象,需要传递一个实例') #错误的调用

object1=Test()生成一个实例,object1.func返回一个绑定的方法,把实例object1和方法func绑定。
而Test.func是用类去引用方法,我们得到一个未绑定的方法对象。要调用它就得传一个实例参数,如t(object1,'未绑定的方法对象,需要传递一个实例') 。大多数时候,我们都直接调用方法,所以一般不会注意到方法对象。但是如果开始写通用的调用对象的代码时,需要特别仔细地注意未绑定方法,它们需要地传一个实例参数。

在类的继承当中,一般子类也会实现一个init方法,这等于是重写了父类的构造方法,那么在子类的构造方法中应该调用父类的构造方法初始化父类的属性,要不然无法使用父类中的属性。在子类中有两种方法可以实现这一目的:调用父类构造方法的未绑定版本,或者使用super函数。

super 是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没问题,但是如果使用多继承,会涉及到查找顺序(MRO)、重复调用(钻石继承)等种种问题。使用非绑定的方法初始化父类的属性时还有一个缺点,即当一个子类的父类发生变化时(如类B的父类由A变为C时),必须遍历整个类定义,把所有的通过非绑定的方法的类名全部替换过来,这样不利于代码的维护。例如:
class A:
def __init__(self):
print "enter A"
print "leave A"

class B(A):
def __init__(self):
print "enter B"
A.__init__(self)
print "leave B"
如果A变成了C,则需要做如下修改:

class B(C): # A --> C
def __init__(self):
print "enter B"
C.__init__(self) # A --> C
print "leave B"

如果代码简单,这样的改动或许还可以接受。但如果代码量庞大,这样的修改可能是灾难性的。

如果使用super函数:
class A(object):    # A must be new-style class
def __init__(self):
print "enter A"
print "leave A"

class B(C): # A --> C
def __init__(self):
print "enter B"
super(B, self).__init__()
print "leave B"
尝试执行上面同样的代码,结果一致,但修改的代码只有一处,把代码的维护量降到最低,是一个不错的用法。因此在我们的开发过程中,super关键字被大量使用,而且一直表现良好。

super函数只能在新式类中使用(新式类:必须有继承的类,如果没有想要继承的,就继承object,应尽量使用新式类;经典类:没有父类)。

例:

#! /usr/bin/env python
# -*- coding: utf-8 -*-

# *************************************************************
# Filename @ bird.py
# Author @ Huoty
# Create date @ 2014-11-01 22:52:41
# Description @
# *************************************************************

__metaclass__ = type # 把所有的old-style 变成 new-style 的类

class Bird: # or class Bird(object)
def __init__(self):
self.hungry = True
def eat(self):
if self.hungry:
print "Aaaah..."
self.hungry = False
else:
print "No, thanks!"

class SongBirdd(Bird):
def __init__(self):
#Bird.__init__(self) # 为绑定的方法
super(SongBirdd, self).__init__() # 绑定的方法
# 当前的类和对象可以作为super函数的参数使用
# 调用super函数返回的对象的任何方法都是调用父类的方法,而不是当前类的方法
# 所以这里调用的是父类的__intit__方法
self.sound = "Squawk"
def sing(self):
print self.sound


# Script starts from here

sb = SongBirdd()
sb.eat()
sb.eat()


参考:
http://blog.csdn.net/johnsonguo/article/details/585193
http://blog.sina.com.cn/s/blog_3fe961ae0100kew0.html
  评论这张
 
阅读(28)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018