Python构造函数,迭代器

来源:互联网 发布:淘宝账号名字大全2015 编辑:程序博客网 时间:2024/05/16 19:19

构造函数

1.  一个对象被创建之后立刻调用构造函数

__function__这种形式的函数会在特殊情况下被调用,如:__init__

两行变一行:
f = FooBar()
f.init()  #这一行就不用调用了

使用__init__:f = FooBar() 即可

# -*- coding: utf-8 -*-class FooBar:    def __init__(self):        self.var = 42f = FooBar()print f.varclass FooBar:    def __init__(self,value = 42): # 赋予参数默认值        self.var = valuef = FooBar('That is it') # 构造方法有参数print f.varf = FooBar() # 构造方法有参数print f.var


2. 继承重写构造方法

如果重写超类的构造方法,那么需要调用超类的构造方法,否则可能会出错:

# -*- coding: utf-8 -*-class Bird:    def __init__(self):        self.hungry = True    def eat(self):        if self.hungry:            print 'Aaah...'            self.hungry = False # 调用了构造方法中的值        else:            print 'No,thanks'b = Bird()b.eat()b.eat()class SongBird(Bird):# 继承超类    def __init__(self):        self.sound = 'Squawk!' # 没有 hungry 特性    def sing(self):        print self.soundsb = SongBird()sb.sing()sb.eat() # 超类有的子类也有

调用超类构造方法解决上述问题:super函数 / 调用超类构造方法未绑定版本

class SongBird(Bird):# 继承超类    def __init__(self):                super(SongBird,self).__init__() # 使用类+对象作为参数        #Bird.__init__(self) # 使用类方法,实例没有被绑定                self.sound = 'Squawk!'    def sing(self):        print self.sound

未绑定方法:没有实例被绑定,可以自由的提供所需要的self 参数


*3. 引申出模仿方法

创建类似序列的对象:

# -*- coding: utf-8 -*-def checkIndex(key): # 检查索引是否合法    if not isinstance(key,(int,long)):raise TypeError    if key<0:raise IndexErrorclass sequence:    def __init__(self, start=0, step=1):# 初始化参数防止出事        self.start = start        self.step = step        self.changed = {}    def __getitem__(self,key): #生成了一个无限长的序列        checkIndex(key)        try:# 异常捕捉的妙用: 改变了值则返回改变的值,没有改变值则返回设定值            return self.changed[key] # self.changed = {}初始化默认为空         except KeyError:#用户没有给序列设定值            return self.start + self.step * key     def __setitem__(self, key, value): #给用户用于修改的        checkIndex(key)        self.changed[key] = values=sequence(1,2)print s[4] # 调用方法__getitem__s[4]=2print s[4],s[5]print s['four']
子类化列表,字符串,字典:

# -*- coding: utf-8 -*-class CounterList(list): # 继承list    def __init__(self, *args):        super(CounterList,self).__init__(*args)        self.counter = 0 # 新增功能:访问技术    def __getitem__(self,index):        self.counter += 1        return super(CounterList,self).__getitem__(index)cl = CounterList(range(10))print cl #没有重写任何方法,超类的都可以用print cl.countercl[4]+cl[2] #访问了两次print cl.counter


迭代器

__iter__方法:迭代器规则的基础,返回一个迭代器

for 循环除了对序列,字典迭代,可以对实现了__iter__方法(返回一个iterator)的对象迭代(使用迭代器的原因:更通用,简单)。

比如需要计算值:迭代器一个个算,列表一次获取所有值,若值很多则很占内存。

使用迭代器实现斐波那契:

# -*- coding: utf-8 -*-class Fibs:    def __init__(self):        self.a = 0        self.b = 1    def next(self):        self.a, self.b = self.b, self.a+self.b        return self.a    def __iter__(self): # 放到会在for循环中使用的对象中        return selffibs = Fibs()for f in fibs: # __iter__    if f>1000:        print f        break
生成一个10以内的迭代器:
# -*- coding: utf-8 -*-class Iteration:    value = 0    def next(self):        self.value += 1        if self.value>10: raise StopIteration        return self.value    def __iter__(self):        return selfti = Iteration()for t in ti:    print t


1. 生成器

包含 yield 语句的函数:生成器

生成器与return不同,生成一个值就pause,下次调用时继续函数,而不会像return 一样终止函数。

所以在处理:任意层嵌套(例如树形结构),并不知道到底有多少层嵌套——需要递归+生成器:

# -*- coding: utf-8 -*        def flatten(nested):    try: #对于一个任意的树形结构,至少应该有两层for循环:两种情况        for sublist in nested: #基本情况:展开一个元素——TypeError            for element in flatten(sublist): # 需要递归的情况:展开可迭代对象                print element                yield element                #return element 找到第一个元素的时候就返回了,无法遍历后面的元素    except TypeError: # 排除TypeError: 'int' object is not iterable, 基本情况:展开一个元素        yield nested        #return nestedprint list(flatten([[[1],2],3,4,[5,[6,7]],8]))
遇到字符串怎么办,因为对字符串进行迭代会导致无穷递归:

def flatten(nested):    try:        try:nested + '' # 检验是否是字符串        except TypeError:pass # 不是则进行下一步        else:raise TypeError # 是字符串就异常终止程序        for sublist in nested:             for element in flatten(sublist):                 print element                yield element    except TypeError:         yield nested

普通函数实现上述:

def flatten(nested):    result = []    try:        try:nested + ''        except TypeError:pass        else:raise TypeError        for sublist in nested:            for element in flatten(sublist):                result.append(element)    except TypeError:        result.append(nested)    return result

一层循环实现:(很局限,首先需要知道每一个元素可能的类型)

# -*- coding: utf-8 -*listx = []def flatten(nested):    #listx = [] 注意位置!在后面调用flatten的时候又会产生一个新的listx    for i in nested:        if type(i) is not list:            listx.append(i)        else:            flatten(i)    return listxprint flatten([[[1],2],3,4,[5,[6,7]],8])
这段代码就要求提前想好 i 可能的类型,而之前的两段代码是直接创造一个可能会出错(如果不是集合类型,而像数字之类的是不能迭代的)的代码,之后的事全交给异常处理来管TypeError,不用预知每个元素可能是什么类型。



0 0
原创粉丝点击