9.2
构造函数:命名为__init__,构造函数不同于普通的方法在于,将在对象创建后自动调用它们。
class FooBar:
def init(self):
self.somevar=42
f=FooBar()
f.somevar
42
9.2.1
在构造函数时,要消除新构造的函数没有包含任何初始化的代码可以用调用未关联的超类构造函数或是使用函数super
9.2.2
调用未关联的超类构造函数:
9.2.3
用函数super与上面的效果相同。
9.3
9.3.1
1.len(self):返回集合包含的项数,对序列来说是元素的个数,对映射来说为键—值对的个数,当_len_的返回值为0时,对象布尔在上下文中视其为假。
2.getitem(self,key):返回与指定键相关联的值,对序列来说返回的是序列中的元素的索引值。即0-n-1的整数。
3.setitem(self,key,value):用这个方法来存储与键相关联的方式来存储值,以便以后用_getitem_来获取。
4.delitem(self,key):这个方法在对对象的组成部分使用_del_语句时被调用,应删除与key相关联的值。
5.对于序列来说如果键为负整数,应从末尾往前数。
6.如果键的类型不合适则会引发TypeError异常。
7.如果序列的索引不在范围内,但合乎类型则会引发IndexError异常。
9.3.2
使用继承能够减免去实现一些方法。
在模块collections中提供了抽象和具体的基类,可以使用继承内置类型。
示例:
9.4
9.5
存取方法:用来获取和设置属性。如果要访问给定属性是必须要采取特定的措施,要像如下封装变量。
示例:
9.5.1
函数property通过将存取方法作为参数(获取方法在前,设置方法在后),创建一个特性,后将某一名称关联到这个特性。(如下面这个程序的size) ,调用函数时可以指定一到四个或者是不指定参数,若没有指定参数创建的特性既不可读也不可写,如果只指定一个参数(获取方法)创建的特性只可读,第三个参数是可选的,指定用于删除属性的方法,第四个参数也是可选的,指定一个文档字符串。这些参数名分别是fget,fset,fdel,doc
示例:
9.5.2静态方法和类的方法
静态方法和类的方法是这样创建的:将他们分别包装在staticmethod和classmethod类的对象中。静态方法的定义中没有参数self,可直接通过调用类来调用。类方法的定义中有类似于self的参数,通常被命名为cls,类的方法可直接通过对象直接调用,参数cls将自动关联。
装饰器:用于对对象方法函数等进行包装(对象必须是可调用的)
示例(调用的时候就无需实例化):
9.5.3
1.getattribute(self,name):在属性被访问时自动调用
2.getattr(self,name):在属性被访问而对象没有这种属性时自动调用。
3.setattr(self,name,value):试图给属性赋值时自动调用。
4.delattr(self,name):试图删除属性时自动调用。
缺点:这些方法用起来与property不方便一些,且效率也低。
9.6迭代器
迭代器的基础__iter__。
9.6.1 迭代器协议
for循环可以迭代的对象:字典,序列,以及实现了方法__iter__的对象。
方法__iter__返回一个迭代器,是一个包含方法__next__的对象,在调用这个方法的时候可以不提供任何参数。在调用方法__next__时,迭代器的返回值试下一个值,若没有下一个值则会引发StopInteration异常。其中next(it)与it.next()等效。
用迭代器而不使用列表的原因:列表占得内存大,使用迭代器更加简单,通用。
示例:
以上的迭代器可以直接用于for循环中。
9.6.2从迭代器到创建序列
除了对迭代器和可迭代对象进行迭代之外,还可以将他们转换为序列使用构造函数list显示地将迭代器转换为列表。
class TestIterator
value=0
def next(self):
self.value+=1
if self.value>10:raise StopIterator
return self.value
def iter(self):
return self
…
…
ti=TestIterator()
list(ti)
…
9.7生成器
定义:生成器是一种使用普通函数语法定义的迭代器。
9.7.1创建生成器
创建一个将嵌套列表展开的函数,这个函数将一个类似于列表的列表作为参数。
示例:
包含yield语句的函数都被称作生成器。生成器与普通函数的区别在于,生成器不使用return返回值,而是可以生成多个值,每次一个,每次使用yield生成一个值后函数将被冻结,即在此停止执行,等待被重新唤醒,在被重新唤醒后,函数将在停止的地方继续开始执行,为生成所有的值可对迭代器进行迭代。
9.7.2递归式生成器
对于处理任意层嵌套的列表可求助于递归。
def flatten(nested):
try:
for sublist in nested:
for element in flatten(sublist):
yield element
except TypeError:
yield nested
调用flatten的两种可能性:基线条件和递归条件。在基线条件下,要求这个函数展开单个元素,在这种情况下,for循环将引发TypeError异常,因为你将试图迭代一个数,因为这个生成器只生成一个数。
对于要展开一个列表,先对他们遍历所有的子列表,并对它们调用flatten,然后再用for循环生成展开后的子列表的所有元素。
如果nensted的对象是字符串,或者是字符串的对象,他就属于序列,就不会引发TypeError的异常。因此flatten一般不用于对字符串的迭代。
开头对于对象类型的检查:
def flatten(nested):
try:
try: nested+’’
except TypeError:pass
else :raise TypeError
for sublist in nested:
for element in flatten(sublist):
yield element
except TypeError:
yield nested
另一种解决方案是使用isinstance以及字符串和类似于字符串类型的对象的一些超类。
9.7.3通用生成器
1.yield意味生成一个值,而return意味着生成器应该停止执行。
2.生成器的组成部分:生成器的函数和生成器的迭代器,前者由def语句定义,包含yield语句。
9.7.4生成器的方法
1.在生成器开始运行后,生成器与外部之间的通信渠道包含两个端点,外部世界和生成器。
2.外部世界:外部世界访问生成器的方法send,只接受一个参数
3.生成器:在被挂起的生成器(遇到第一个yield)内部,yield作为表达式而非语句,即为重新运作时yield返回一个值——通过send向外部世界发送的值,如果使用的是next,yield的返回值是none。
示例:
4.throw方法:在生成器内引发异常,调用时可以提供一个异常类型,可选值和一个traceback对象。
5.close方法:用于停止生成器,调用时无需提供任何参数。
9.7.5模拟生成器
9.8八皇后问题
9.8.1生成器的回溯
图:
http://mathworld.wolfram.com/Graph.html
最常见的类型是图形,其中至多一个边缘(即,一个边缘或没有边缘)可以连接任何两个顶点。这些图形称为简单图形。如果顶点之间允许多个边,则该图称为多图。顶点通常不允许自我连接,但有时会放宽此限制以允许此类“ 图形循环”。可能包含多个边和图循环的图形称为伪图。
树:
https://xlinux.nist.gov/dads/HTML/tree.html
1)从根节点开始访问的数据结构。每个节点都是叶子或内部节点。内部节点具有一个或多个子节点,并称为其子节点的父节点。同一节点的所有孩子都是兄弟姐妹。与物理树相反,根通常描绘在结构的顶部,叶子描绘在底部。(2)连接,无向,非循环图。除非另有说明,否则它是有根和有序的。
9.8.2八皇后问题描述
9.8.3状态表示
用元组来表示可能的解。
9.8.4检测冲突
9.8.5基线条件
9.8.6递归条件