Python学习笔记(九)魔法方法,属性和迭代器

9.2构造方法

   构造方法和普通方法的不同之处在于,当一个对象被创建后,会立即调用构造方法。

   

class FooBar:
    def __init__(self):
        self.somevar=42
f=FooBar()
>>>f.somevar
42

9.2.3super函数

   当子类重写了父类的某一方法后,如果想调用父类的这一方法,可以使用super函数。

class Bird:
    def __init__(self):
        self.hungry=True
def eat(self):
    ifself.hungry:
             print('Aaaah')
classSongBird(Bird):
    def __init__(self):
        super(SongBird,self).__init__()
        self.sound='squawk'
    def sing(self):
        print(self.sound)
>>>sb=SongBird()
>>>sb.sing()
squawk
>>>sb.eat()
Aaaah
 


上例中,首先在重写的构造方法中调用了父类的构造方法,使子类获得hungry属性,然后又加入了自己的sound属性。

9.3成员访问

9.3.1基本的序列和映射规则

序列和映射是对象的集合。为了实现他们基本的行为,如果对象时不可变的,就需要使用两个魔法方法,如果是可变的则需要使用4个。

__len__(self): 返回集合中所有项目的数量。如果是映射,则返回键值对的数量。如果返回0,则会被当作一个布尔变量

__getitem__(self,key)返回与对应的键对应的值,对于一个长度n的序列,键是一个0-n-1的整数

__setitem__(self,key,value):根据一定的方式存储和key对应的value,只能用于可修改对象。

__delitem__(self,key):这个方法对一部分对象使用del语句时被调用

对于一个序列来说,负整数从末尾开始计数,换句话说 x[-n]和x[len(x)-n]是一样的。

9.3.1子类化列表,字典和字符串。

下面例子,带有访问计数的列表

  

  class CounterList(list):
    def __init__(self,*args):
        super(CounterList,self).__init__(*args)
        self.counter=0
    def __getitem__(self,index):
        self.counter+=1
        returnsuper(CounterList,self).__getitem__(index)

在CounterList类中,重写了父类的__init__ 和__getitem__方法, 在构造方法中初始了counter属性,每次列表元素被访问时这个值加一。

cl=CounterList(range(10))
>>> cl
[0, 1, 2, 3, 4, 5,6, 7, 8, 9]
>>>cl[2]+cl[4]
6
>>>cl.counter
2


9.4更多魔力

   略

9.5属性

9.5.1property函数

   

class Rectangle:
    def __init__(self):
        self.width=0
        self.height=0
    def setSize(self,size):
        self.width,self.height=size
    def getSize(self):
        return self.width,self.height
size=property(getSize,setSize)
r=Rectangle()
>>> r.width=10
>>> r.height=5
>>> r.size
(10, 5)
 

9.6迭代器

9.6.1迭代器规则

   __iter__方法返回一个迭代器,所谓我的迭代器就是具有next方法的对象。在调用next方法时,迭代器会返回它的下一个值。

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

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):
               return self


                             

在遍历过程中使用迭代器,自动算出下一个值

>>> fibs=Fibs()
>>> for f in fibs:
      iff>1000:
             print(f)
             break
 
     
1597


9.7生成器

   生成器是一种用普通函数语法定义迭代器。

9.7.1创建生成器

参数是一个列表 如下形式:

>>> nested=[[1,2],[3,4],[5]]


函数应该按顺序打印出列表中的数字:

def flatten(nested):
      for sublistin nested:
             forelement in sublist:
                    yieldelement


任何包含yield语句的函数称为生成器。每次产生一个值(使用yield语句),函数就会被冻结:即函数停在那点等待被激活。函数被激活后就从停止的那点开始被激活:

下面通过在生成器上迭代来使用上面的值

f

or num in flatten(nested):
      print(num)
 
     
1
2
3
4
5

9.7.2递归生成器

    当不知道需要使用几层嵌套的时候,应该使用更灵活的,递归的方法:

def flatten(nested):
        try:
               for sublist in nested:
                       for element in flatten(sublist):
                                yield element
        exceptTypeError:
               yield nested


当flatten被调用时,有两种可能:基本情况和需要递归的情况。 在基本情况,函数会被告知展开一个元素(比如一个数字),这种情况下,会引发一个TypeError异常(因为试图对一个数字进行迭代),生成器会产生一个元素。

如果展开一个列表(或者其他的可迭代对象),那么就要进行特殊处理。

9.7.3通用生成器

生成器由两部分组成:生成器的函数和生成器的迭代器

 

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值