Python基础编程(九)魔法方法、属性和迭代器

在Python中,有的名称会在前面和后面都加上两个下划线。

在Python中,由这些名字组成的集合所包含的方法称为魔法(或称特殊)方法。

9.2 构造方法

构造方法代表着以前例子中使用过的init的初始化方法。但构造方法和其他普通方法不同的地方在于,当一个对象被创建后,会立即调用构造方法。
class Foobar:
      def __init__(self):
          self.aomevar = 42
>>>f = Foobar()
>>>f.somevar
42

9.2.1 重写一般方法和特殊的构造方法

重写是继承机制中的一个重要内容,对于构造方法尤其重要。构造方法用来初始化新创建对象的状态,大多数子类不仅要拥有自己的初始化代码,还要拥有超累的初始化代码。
如果一个类的构造方法被重写,那么需要调用超类的构造方法,否则对象可能不会被正确的初始化。
考虑下面的Bird类:
class Bird:
      def __init__(self)
          self.hungry = True
      def eat(self):
          if self.hungry:
             print 'Aaaah...'
             self.hungry = False
          else:
               print 'No, thanks!'
>>> b = Bird()
>>> b.eat()
Aaaah...
>>> b.eat()
No, thanks!
现在考虑子类SongBird:
class SongBird(Bird)
      def __init__(self):
          self.sound = 'Aquawk!'
      def sing(self):
          print self.sound
>>> ab = SongBird()
>>> sb.sing()
Squawk!
尝试在SongBird中调用eat方法sb.eat(),就会产生一个问题:
异常说明了错误,SongBird没有hungry特性,原因:在SongBird中,构造方法被重写,担心的构造方法没有任何关于初始化hungry特性的代码。
为了达到预期效果,SongBird的构造方法必须调用其超类Bird的构造方法来确保进行基本的初始化。有两种方法能达到这个目的:调用超类构造方法的未绑定函数,或者使用super函数。

9.2.2 调用未绑定的超类构造函数

class SongBird(Bird):
      def __init__(self):
          Bird.__init__(self)
          self..sound = 'Squawk!'
      def sing(self):
          print self.sound
只添加了一行代码——Bird.__init__(self)。
>>> sb = SongBird()
>>> sb.sing()
Squawk!
>>> sb.eat()
Aaaah...
>>> sb.eat()
No, thanks!
在调用一个实例的方法时,该方法的self参数会被自动绑定到实例上(绑定方法),但如果直接调用类的方法(比如Bird.__init__),那么就没有实力会被绑定,这样就可以自由的提供需要的self参数。称为未绑定方法。

9.2.3 使用super函数

class SongBird(Bird):
      def __init__(self):
          super(SoundBird.self).__init__()
          self..sound = 'Squawk!'
      def sing(self):
          print self.sound
结果如上面的方法。

9.3 成员访问

基本的序列和映射的规则很简单,但是如果要实现它们全部功能就需要实现很多魔法函数。

9.3.1 基本的序列和映射规则

class ArithmeticSequence:
      def __init__(self,start=0,step=1):
          self.start = start
          self.step = step
          self.changed = ( )
      def __get__(self,key)
          checkIndex(key)
          try: return self.changed[key]
          except KeyError:
               return self.start + key*self.strp
      def __setitem__(self,key,value)
          checkIndex(key)
          self.changed[key] = value
 这里实现的是一个算数序列,该序列的每个元素都比它前面的元素大一个常数。
>>> s = ArithmeticSequense(1,2)
>>> s[4]
9
>>> s[4] = 2
>>> s[4]
2
>>> s[5]
11
注意观察结果是怎么实现的。
__len__(self):这个方法应该返回集合中所有项目的数量。对于序列来说,这就是元素的个数;对于映射来说,则是键-值对。
__getitem__(self,key):这个方法返回所给键对应的值。
__setitem__(self,key,value):这个方法应该按一定的方式存储和key相关的value。
__delitem__(self,key):这个方法在对一部分对象使用del语句是被调用,同时必须删除和元素相关的键。
























 

posted @ 2014-05-22 15:36  Mave  阅读(183)  评论(0编辑  收藏  举报