当前位置: 代码迷 >> 综合 >> Python入门基础第十七课--方法、属性、迭代器等
  详细解决方案

Python入门基础第十七课--方法、属性、迭代器等

热度:53   发布时间:2023-09-27 09:53:41.0

1.前言

    本节的内容是续着上上一节的内容来讲的,面向对象在Python里面是非常重要的一个概念。第十五课讲了一些关于面向对象的饿知识,但是还是不够的。这一章节我们再来补充些。一些很好用的方法和特性。一起来看看吧。

2.super函数

    super函数是干什么的?有什么用呢?

    super是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没问题,但是如果使用多继承,会涉及到查找顺序、重复调用等种种问题。具体的我们来看看下面这个例子。

__metaclass__=typeclass Bird():def __init__(self):self.hungry=Truedef eat(self):if self.hungry:print 'Aaaaah...'self.hungry=Falseelse:print 'No thanks..'class SongBird(Bird):def __init__(self):super(SongBird, self).__init__() #这样的调用方式要求父类必须是新式类,继承自object。假如你不想用这样的调用方式,那么久要显示调用父类方法:Bird.__init__(self)self.sound='Squawk!'def sing(self):print self.soundsb=SongBird()
sb.sing()
sb.eat()
sb.eat()

  下面是它的运行结果:

/usr/local/bin/python2.7 /Users/yangjiayuan/PycharmProjects/day/day15/function_of_super.py
Squawk!
Aaaaah...
No thanks..Process finished with exit code 0

    关于super函数的内部工作原理在这不做过多介绍,大家可以自行百度。但是必须知道的一点就是:在大多数情况下,使用新式类和super函数是比调用超类的未绑定的构造方法更好的选择。

3.成员访问

    在前面,我们介绍过一些关于成员访问的知识。尽管__init__方法是到目前为止提到的最重要的特殊方法,但是还有一些其他方法提供的作用也很重要。下面列出的就值得关注。

3.1基本序列和映射规则

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

__len__(self)方法 这个方法返回集合中所含项目的数量。对于序列来说,这就是元素的个数。对于映射来说,则是键-值对的数量。若返回0则为空。(空列表、空元组、空字符串、空字典等等)
__getitem__(self,key)方法 这个方法返回与所给键对应的值。序列里面,键应该是0~n-1的整数,n是序列的长度。而对于映射来说,可以使用任意类型的键。
__setitem__(self,key,value)方法 这个方法按一定的方式存储和key相关的value,该值以后可以通过__getitem__来获取。只能为可以修改的对象使用这个方法。
__delitem__(self,key) 这个方法在对一部分对象使用del语句的时候被调用,同时必须删除和键相关测键。也是可以用来修改对象定义的。并不是删除全部的对象,而是移除一些需要移除的元素。

    我们可以在需要的时候采用这些方法,另外这些方法还需要一定的附加条件:

  • 序列中,如果键是负整数,那么要从末尾开始计数。
  • 如果键不是合适的类型就会引发一个类型错误,TypeError异常。
  • 如果序列的索引是正确的类型,但是超出了范围,则会引发一个IndexError异常。

    来看看使用上面方法的例子:    

def checkIndex(key):if not isinstance(key,(int, long)) :raise TypeErrorif key<0:raise IndexErrorclass AirthmeticSequence:def __init__(self,start=0,step=1):self.start=startself.step=stepself.changed={}def __getitem__(self, key):checkIndex(key)try:return self.changed[key]except KeyError:return self.start + key*self.stepdef __setitem__(self, key, value):checkIndex(key)self.changed[key]=values=AirthmeticSequence(1,2)
s[4]=2
print s[4]
print s[5]

    需要解释的是一些函数:isinstance()函数用来判断一个对象是否是一个已知的类型,类似于type()。type()不会认为 子类是一种父类类型,不考虑类的继承关系。而isinstance()会认为子类是一种父类类型,考虑继承关系。对应上面的列表,自己实现一下上面的程序,看看最后的结果。

3.2子类化列表、字典和字符串

    前面的方法是很好用,但是实现起来很麻烦。你需要注意很多细节方面的东西才能很好的使用它们。这时候你可能会想到,如果这样的方法能继承下来多好,就不用这么麻烦了,这样的想法确实在Python里面是可行的。标准库有三个关于序列和映射规则:UserList、UserString、UserDict可以立即使用的实现。来看看:

class CounterList(list):def __init__(self,*args):super(CounterList,self).__init__(*args)self.counter=0def __getitem__(self, index):self.counter+=1return super(CounterList,self).__getitem__(index)c1=CounterList(range(10))
print c1
c1.reverse()
print c1
del c1[3:6]
print c1
print c1.counter
print c1[4]+c1[2]
/usr/local/bin/python2.7 /Users/yangjiayuan/PycharmProjects/day/day15/funciton_of_classlist.py
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
[9, 8, 7, 3, 2, 1, 0]
0
9
2Process finished with exit code 0

    程序现实的饿结果如上所示,就如你看到的一样,CounterList在很多地方和列表的作用一样,但是它有一个counter特性。每次列表元素被访问的时候它都会自增,当然初始值为0。当c1[4]和c1[2]被访问后,很明显的是c1.counter的值从0变到2。

4.迭代器

    迭代器我们在前面的知识里面也提到过,迭代器最基础的就是一个__iter__方法,这个方法是迭代器规则的基础。

    迭代器意味着我们可以重复做一些事情很多次,就像在循环处理的那里一样。__iter__方法会返回一个迭代器,所谓的迭代器就是具有next的方法,方法调用的时候不需要任何参数。在调用next方法的时候,迭代器会返回它的下一个值。如果next方法被调用,但是迭代器没有值可以返回,此时就会引发一个StopIteration异常。来看一个例子:

class Fibs:def __init__(self):self.a=0self.b=1def next(self):self.a,self.b=self.b,self.a+self.breturn self.adef __iter__(self):return selffibs=Fibs()for f in fibs:if f>1000:print fbreak
/usr/local/bin/python2.7 /Users/yangjiayuan/PycharmProjects/day/day15/use_of_iteration.py
1597Process finished with exit code 0

    上述例子是实现斐波那契数列的另外一种方法,也就是利用迭代器。这个方法本身返回迭代器本身。很常见的是,__iter__和for循环在一起使用,会放到其他的会在for循环中使用的对象中。这样一来,程序就能返回所需的迭代器。就像上面的一样,我们试着查找在斐波那契数列中比1000大的数里面最小的数,如果找到这个数就终止循环,否则程序循环一直进行下去。除了这样的操作以外,我们还可以从迭代器获得序列--利用list构造方法显示地将迭代器转换为列表。

class TestIteration:value=0def next(self):self.value+=1if self.value>10:raise StopIterationreturn self.valuedef __iter__(self):return selfti=TestIteration()
print list(ti)
/usr/local/bin/python2.7 /Users/yangjiayuan/PycharmProjects/day/day15/use_of_iteration.py
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]Process finished with exit code 0

    从运行结果可以看出,我们确实将迭代器通过list方法转换为了序列并打印了出来。

    好咯,这一章节的内容就先介绍到这里啦,多练习最好。下一章节将会介绍一个新的概念--生成器和一个小项目的实现。




  相关解决方案