20161217py学习笔记:魔法方法/

 

1、魔法方法也是method,也是定义class中用到函数,只不过这些函数的名字,前后都是双下划线。

  初始化:__init__

  class FooBar:

    def __init__(self,value=42):

      self.somevar=value

  原来想用‘somevar’,大概得这么写:

    >>>f=FooBar()

    >>>f.__init__

    #如果__init__下还有几个self.some*,这么一写得全引用出来,但是我们想用的只是somevar,所以用__init__可以写成如下形式:

    >>>f=FooBar()

    >>>f.somevar #定义在初始化中,直接就拿来用

    >>>42

    #加个参数也可以:

    >>>f=FooBar('this is a constructor argument')

    >>>f.somevar

    >>>this is aconstructor argument

 

2、superclass与subclass都有构造方法的情况下,subclass如何调用superclass的构造方法

class Bird:
  def __init__(self):#这是类的方法
  self.hungry=True
  def eat(self):#这是实例的方法
    if self.hungry:
      print'Aaaah...'
      self.hungry=False
    else:
      print'No,thanks!'

class SongBird(Bird):
  def __init__(self):
    self.sound='Squawk!'
  def sing(self):
    print self.sound

>>>sb=SongBird()

>>>sb.eat()

会报错,因为subclass的构造方法把superclass的覆盖了。

在subclass中添加superclass的构造方法

做如下修改:

class SongBird(Bird):
  def __init__(self):

    Bird.__init__(self)#在subclass的构造方法中,加上superclass的构造方法
    self.sound='Squawk!'
  def sing(self):
    print self.sound

但是输出时,会变得比较奇怪。

>>>sb=SongBird()

>>>sb.eat()

>>>'Aaaah...'

>>>sb.eat()

>>>'No,thanks'

这是因为在调用实例的方法时,self参数会被自动绑定到实例上(这也是上面的例子(***),为什么直接调用sb.eat()会说no thanks),if句子根本没起作用;

直接调用类的方法(Bird.__init__),就没有实例被绑定。

使用superclass直接调用

class SongBird():

  def __init__():

    super(Bird,self).__init__()

    self.sound='Squawk!'
  def sing(self):
    print self.sound

3、魔法方法之基本的序列和映射规则

 

def checkIndex(key):
  '''所给的键是能接受索引的吗?为了能被接受,键应该是一个非负的整数。如果它不是一个整数,会引发TypeError;如果是负数,会引发IndexError。(因为序列是无限长的)。

  if not isinstance(key,(int,long)):raise TypeError
  if key<0: raise IndexError

 

class ArithmeticSequence:
  def __init__(self,start=0,step=1):
  '''

  初始化算术序列

  self.start,序列中的第一个值

  self.step,两个相邻的差值

  self.changed,用户修改的值得字典

  self.start=start
  self.step=step
  self.changed={}

 

  def __getitem__(self,key):
  '''
  Get an item from the aritmetic sequence.
  '''
  try: return self.changed[key] #修改了吗?
  except KeyError: #否则...
    return self.start+key*self.step #...计算值

 

  def __setitem__(self,key,value):
  '''
  修改算术序列中的一个项
  '''
  checkIndex(key)
  self.changed[key]=value #保存更改后的值

 

4、子类化list/dict/string

class CounterList(list):#subclass CounterList继承了superclass list的特性
  def __init__(self,*args):
    super(CounterList,self).__init__(*args)#super函数,调用superclass list的构造方法
    self.counter=0
  def __getitem__(self,index):#重写了__getitem__方法
    self.counter+=1
    return super(CounterList,self).__getitem__(index)

 

posted @ 2016-12-17 00:31  饶慕洵  阅读(172)  评论(0编辑  收藏  举报