python

python 魔法方法,属性和迭代器

2015-11-02  本文已影响441人  森先生_wood

(一)魔法方法

在python中,有的名称在前后会加上两个下划线,具有特殊的含义,大部分会在某些条件下自动被调用。这里简单介绍几种重要的魔法方法。当然这是所有用途中的一小部分。

(1)构造方法

在类的定义中,我们常常加入构造方法。这样我们在创建该类的实例时,会自动执行该方法:

class Bird(object):
  def __init__(self):
      self.hungry=Ture`

构造方法继承的注意事项

当我们创建一个类,并从它的超类中继承构造方法时,我们经常需要重写构造方法。比如下面这个例子:

class SongBird(Bird):
  def __init__(self):
    self.sound='squake'`

但是我们需要注意,这样的话这个类的实例就没有了hungry的特性。为了让两种构建方法都执行,我们可以采取调用超类构造方法的未绑定版本或者使用super函数:
# 调用超类构造方法的未绑定版本
def init(self):
Bird.init(self)
self.sound='squake'

#使用super函数(会调用SongBird的所有超类的构造函数 )
def __init__(self):
super(SongBird,self).__init__()
self.sound='squake'

(2)成员访问

我们都知道,基本的序列有a[],a[2:3]这样的成员访问功能,我们如果需要我们自己创建的类也有这样的功能,就需要类有两种魔法方法就可以了。(如果成员可变,需要四个)
1, len(self):
2, getitem(self,key):
3, setitem(self,key,value):
4, delitem(self,key):

当然我们可以直接把类的超类设置成list,然后将我们需要修改的魔法方法重写就可以了。

(二)属性

有时候对象的特性之间存在关系,比如size由width和height组成,一旦size变化,后两者也会变化;反之同理。于是我们需要一种特殊的特性:属性。属性并不是在init中直接定义,而是通过访问器(get,set等方法)定义的特性。
创建属性的机制大致上有property函数,__getattr__等魔法方法。

__getattr__(self,name):当特性name被访问时被自动调用
__getattr__(self,name):当特性name被访问且没有相应对象时被自动调用
__setattr__(self,name,value):在试图给特性name赋值时会被自动调用
__delattr__(self,name):在试图删除特性name时会被自动调用

  class Rectangle:
    def __init__(self):
        self.width=0
        self.height=0
    def __setattr__(self,name,value):
        if name=='size':
            self.width,self.height=size
        else:
            self.__dict__[name]=value
    def __getattr__(self,name):
        if name=='size':
            return self.width,self.height
        else:
            raise AttributeError

迭代器

我们之前已经遇到了很多可以迭代的对象。序列的类就可以实现for a in lists这样的操作。为了使我们自己定义的类也是可迭代对象,我们需要在类中定义__iter__的方法,它会返回一个迭代器。
迭代器是指拥有next()方法的对象,这样我们就可以循环下去了。为了方便起见,推荐我们定义的类有next()方法和__iter__方法,后者返回的迭代器用自己就行了。

class Fibs:
    def __init__(self):
        self.a=0
        self.b=0
    def next(self):
        self.a,self.b=self.b,self.a+self.b
        return self.a
    def __iter__(self):
        return self

for one in Fibs():
    if(one>100):
        print one
        break

生成器

生成器函数是一种特殊的函数,函数会返回一个生成器(可以像其它迭代器一样使用)。相对于普通函数直接生成一个列表,再对列表进行迭代的优点是对于较大规模的数据,它会逐个生成结果,节约了大量空间,如果中途需要结束的话也不用再生成后续结果。这就是迭代的优势。
生成器的核心是yield语句,和return语句不同的是,它不仅返回值,而且会在该处冻结函数,函数重新被唤醒后从该点继续执行。

def flatten(nexted):
    for sublist in nested:
        for element in sublist:
            yield element

nested=[[1,2],[2,6],[5]]
for num in flatten(nested):
    print num
上一篇下一篇

猜你喜欢

热点阅读