第7章 类和Iterators

第7章 类和Iterators

(1)定义类,只要以保留字class开头,然后跟随“类名”就可以:

class PapayaWhip:               ①
    pass                 

  1. 类名PapayaWhip,并且它没有继承任何其它类。通常类名大写单词首字母,这是个习俗不是语法要求。
  2. 类中的的语句都要缩进,第一句没有缩进的语句,代表类的结束。pass是一个占位关键字,不执行任何操作。

(2)C++程序员可能会感觉奇怪,这个类中没有构造函数也没有析构函数,但是在python中有另一个类似的方法:__init__()

class Fib:
     '''iterator that yields numbers in the Fibonacci sequence'''                              ①
     def __init__(self, max):              ②

  1. 类和模块、函数一样可以有docstring
  2. __init__()方法在实例建立后会被立即调用。技术上讲不应该手动调用这个方法。
  3. 每一个类的方法中的第一个参数(包含__init__()方法),一直是类实例的引用——根据习俗被命名为self。这个参数占据了c++和java的this保留字的位置,但是self在python中并不是一个保留字,仅仅是一个命名习惯。(注:非常强硬的习俗,不要用别的,只用self,记住)
  4. 在__init__()方法中self指向一个新建对象;在类的其它方法中它指向调用方法的实例。虽然在定义方法时要显示的写self,但在调用方法的时候不用显示的写self。

(3)实例化一个类,就像使用函数一样,写上__init__()所需的参数就可以:

>>> import fibonacci2
>>> fib = fibonacci2.Fib(100)                ①
>>> fib                                 ②
<fibonacci2.Fib object at 0x00DB8810>
>>> fib.__class__                       ③
<class 'fibonacci2.Fib'>
>>> fib.__doc__                       ④
'iterator that yields numbers in the Fibonacci sequence'

  1. 创建了一Fib类的实例(fibonacci2模块包),新建的实例分配到变量fib上。所传的参数正是__init__()方法的第二个参数。
  2. 现在fib是Fib类的一个实例了。
  3. 每个类实例都有一个内建属性__class__——它指明对象的类。
  4. 可以访问类的docstring,一个类的所有实例共享相同的docstring.

(4)实例变量

定义在类内部的变量,归属于类

(5)Iterator——迭代器

  1. 迭代器就是类中定义的__iter__()方法。
  2. 在类上调用next()时,类中的__next__()方法会被调用。不要在__next__()方法里使用yield返回值,用return代替。
  3. 以for n in Fib(1000)为例解释其中发生了什么:
    首先,Fib(1000)建立了一个实例,假设名为fib_inst;
    其次,for循环会调用iter(fib_inst),它会执行fib__inst.__iter__(),返回一个迭代器对象——假设名为fib_iter。
    然后,for循环会调用next(fib_iter)——fib_iter.__next__(),for循环会得到这个调用的返回值,并把它赋给n,然后再进入循环体。
    最后,当__next__()引发一个StopIteration异常时,循环停止。

def __iter__(self):

    self.a=0

    self.b=1

    return self

 

def __next__(self):

    fib=self.a

    if ifb > self.max:

        raise StopIteration

    self.a, self.b = self.b, self.a+self.b

    return fib

发表回复