- 9.1 基本概念
- 9.2 构造函数
- 9.2.1 重写构造函数
- 9.2.2 调用未关联的超类构造函数
- 9.2.3 使用函数 super
- 9.3 元素访问
- 9.3.1 基本的序列和映射协议-None
- 9.3.2 从 list、dict 和 str 派生
- 9.4 其他特殊方法-None
- 9.5 特性
- 9.5.1 函数 property
- 9.5.2 静态方法和类方法
- 9.5.3 __getattr__、__setattr__等方法-None
- 9.6 迭代器
- 9.6.1 迭代器协议
- 9.6.2 从 iterator 创建序列-None
- 9.7 generator(生成器)
- 9.7.1 创建 generator
- 9.7.2 递归式生成器
- 9.7.3 通用生成器-None
- 9.7.4 generator 的方法
- 9.7.5 模拟 generator-None
- 9.8 八皇后问题-None
9.1 基本概念
- 以双下划线开头和结尾的方法,大多是特殊方法的名称;
不可在函数中创建这种类型的名称;
- property:特性;
iterator:迭代器;
9.2 构造函数
- 构造函数(constructor):init(),用于初始化;
构造函数将在对象创建时,被自动调用;
- 析构函数(destructor);
9.2.1 重写构造函数
- 若在子类中重写构造函数,则超类中的构造函数将不能在子类中被应用(因为被覆盖了);
solution:
- 调用未关联的超类构造函数;
- 使用函数 super(在较新版本的 Python 中,应使用本方法) ;
9.2.2 调用未关联的超类构造函数
>>> class Bird:
... def __init__(self):
... self.hungry = True
... def eat(self):
... if self.hungry:
... print('Aaaah ...')
... self.hungry = False
... else:
... print('No, thanks!')
... class SongBird(Bird):
... def __init__(self):
... Bird.__init__(self)
... self.sound = 'Squawk!'
... def sing(self):
... print(self.sound)
- 对实例调用方法时,self 参数将自动关联到实例,称之为关联的方法;
- 通过类调用方法(e.g. Bird.__init__),则没有实例与之相关联,称之为未关联的方法;
9.2.3 使用函数 super
- 使用 super().__init__() 语句,替换 9.2.2 中的 Bird.__init__(self);
- 调用 super(当前类的名称, self) 函数时,使用当前类和当前实例(形参为 self )作为参数,返回超类;
此时调用的方法为超类的方法,而非当前类的方法;
- 调用 super() 函数时,可不提供任何参数;
9.3 元素访问
9.3.1 基本的序列和映射协议-None
9.3.2 从 list、dict 和 str 派生
>>> class CounterList(list):
... def __init__(self, *args):
... super().__init__(*args)
... self.counter = 0
... def __getitem__(self, index):
... self.counter += 1
... return super(CounterList, self).__getitem__(index)
9.4 其他特殊方法-None
9.5 特性
- property(特性):通过存取方法定义的 attribute ;
9.5.1 函数 property
- 函数 property 可避免编写大量存取 attribute 的方法;
- property(fget, fset, fdel, doc)
该函数四个参数均为可选参数;
若不指定任何参数,则创建的特性不可读且不可写;
>>> class Rectangle:
... def __init__(self):
... self.width = 0
... self.height = 0
... def set_size(self, size):
... self.width, self.height = size
... def get_size(self):
... return self.width, self.height
... size = property(get_size, set_size)
>>> r = Rectangle()
>>> r.size = 150, 100
9.5.2 静态方法和类方法
- 使用 staticmethod、classmethod 方法后,无需实例化即可调用类中定义的方法;
>>> class MyClass:
... def smeth():
... print('This is a static method')
... smeth = staticmethod(smeth)
... def cmeth(cls):
... print('This is a class method of', cls)
... cmeth = classmethod(cmeth)
>>> class MyClass:
@staticmethod # 装饰器;
def smeth():
print('This is a static method')
@classmethod # 装饰器;
def cmeth(cls):
print('This is a class method of', cls)
9.5.3 __getattr__、__setattr__等方法-None
9.6 迭代器
9.6.1 迭代器协议
- iterate(迭代):可用于 list 、dictionary 等对象或其他实现了方法 __iter__的对象;
- 可迭代对象:实现了方法 __iter__;
迭代器:实现了方法 __next__,该方法用于使迭代器返回下一个值;
iterator 包含方法 __iter__ 和 __next__ ;
- 内置函数 iter() 将可迭代对象转换为迭代器, e.g. iter([1, 2, 3]) ;
- 内置函数 next() 返回可迭代对象的下一个值,若 iterator 没有可供返回的值,则引发 StopIterator 异常;
>>> 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()
>>> from collections import Iterator
>>> isinstance(fibs, Iterator)
9.6.2 从 iterator 创建序列-None
9.7 generator(生成器)
- 包含 yield 语句的函数被称为 generator ;
- generator 返回 iterator ;
- 创建generator:把列表生成式的[]改成()即可;
- 执行含有关键字yield的generator函数:
每次调用next()的时候执行,遇到yield语句返回,返回值断点在yield右侧,再次执行时从上次返回的yield语句处继续执行;
9.7.1 创建 generator
9.7.2 递归式生成器
>>> nest = [[1,[2, 3], 4], [5, 6], [7]]
>>> def flatten(nested):
... try:
... for sublist in nested:
... for element in flatten(sublist):
... yield element
... except TypeError:
... yield nested
... list(flatten(nest))
9.7.3 通用生成器-None
9.7.4 generator 的方法
- 仅当 generator 被挂起后(遇到第一个 yield后),使用 send 才有意义;
若需要在此前向 generator 提供信息,可使用生成器函数的参数;
- generator 重新运行时,yield 返回通过 send 方法从外部世界发送的值;
若使用的是 next(),则返回 None;
- generator 的 method;
method |
function |
.send(argument) |
向生成器提供信息 |
throw |
用于在 generator 中( yield 表达式处)引发异常,调用时可提供一个异常类型、一个可选值、一个 traceback 对象 |
close |
停止 generator,不必提供参数 |
9.7.5 模拟 generator-None
9.8 八皇后问题-None