#魔法方法, 属性 和 迭代器
D:\>python
Python 2.7.5 (default, May 15 2013, 22:43:36) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
#9.1准备工作
>>> __metaclass__=type
>>> class NewStyle(object):
... pass # more_code_here
...
>>> class OldStyle:
... pass # more_code_here
...
#9.2 构造器(constructor)
>>> class FooBar:
... def __init__(self):
... self.somevar = 42
...
>>> f = FooBar()
>>> f.somevar
42
>>>
>>> class FooBar:
... def __init__(self, value=42):
... self.somevar = value
...
>>> f = FooBar('This is a constructor argument')
>>> f.somevar
'This is a constructor argument'
#9.2.1 重写一般方法和特殊的constructor
>>> class A:
... def hello(self):
... print "Hello, I'm A."
...
>>> class B(A):
... pass
...
>>> a = A()
>>> b = B()
>>> a.hello()
Hello, I'm A.
>>> b.hello()
Hello, I'm A.
>>>
>>> class B(A):
... def hello(self):
... print "Hello, I'm B"
...
>>> b = B()
>>> b.hello()
Hello, I'm B
>>> class Bird:
... def __init__(self):
... self.hungry = True
... def eat(self):
... if self.hungry:
... print 'Aaaah...'
... else:
... print 'No, thanks!'
...
>>> class Bird:
... def __init__(self):
... self.hungry = True
... def eat(self):
... if self.hungry:
... print 'Aaaah...'
... self.hungry = False
... else:
... print 'No, thanks!'
...
>>> b = Bird()
>>> b.eat()
Aaaah...
>>> b.eat()
No, thanks!
>>> class SongBird(Bird):
... def __init__(self):
... self.sound = 'Squawk!'
... def sing(self):
... print self.sound
...
>>> sb = SongBird()
>>> sb.sing()
Squawk!
>>> sb.eat()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 5, in eat
AttributeError: 'SongBird' object has no attribute 'hungry'
>>>
#9.2 调用未绑定的超类构造器
>>> class SongBird(Bird):
... def __init__(self):
... Bird.__init__(self)
... self.sound='Squark!'
... def sing(self):
... print self.sound
...
>>> sb = SongBird()
>>> sb.sing()
Squark!
>>> sb.eat()
Aaaah...
>>> sb.eat()
No, thanks!
#9.2 使用super函数
#conding = utf-8
__metaclass__ = type # super() only works in new style classes
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):
super(SongBird, self).__init__() # 在Python 3.0 中, super函数可以不用任何参数进行调用, 功能依然具有"魔力"
self.sound = 'Squark!'
def sing(self):
print self.sound
sb = SongBird()
sb.sing()
sb.eat()
sb.eat()
#python tt.py
#Squark!
#Aaaah...
#No, thanks!
#9.3 成员访问
#9.3.1 基本的序列和映射规则
#coding = utf-8
def checkIndex(key):
"""
所给的键时能接受的索引吗?
为了能被接受, 键应该是一个非负的整数. 如果它不是一个整数, 会引发TypeError; 如果它是负数, 则会引发IndexError(因为序列是无限长的)
"""
if not isinstance(key, (int, long)): raise TypeError
if key<0: raise IndexError
class ArithmeticSequence:
def __init__(self, start=0, step=1):
"""
初始化算术序列
起始值:序列中的第一个值
步长: 两个相邻值之间的差别
改变: 用户修改的值的字典
"""
self.start = start #保存开始值
self.step = step #保存步长值
self.changed = {} #没有项被修改
def __getitem__(self, key):
"""
Get an item from the arithmetic sequence.
"""
checkIndex(key)
try: return self.changed[key] #修改了吗?
except KeyError: #否则...
return self.start + key*self.step #...计算值
def __setitem__(self, key, value):
"""
修改算术序列中的一个项
"""
checkIndex(key)
self.changed[key]=value # 保存更改后的值
s = ArithmeticSequence(1, 2)
print s[0]
print s[1]
print s[2]
print s[3]
print s[4]
s[4]=2
print s[4]
print s[5]
#del s[4]
#Traceback (most recent call last):
# File "tta.py", line 51, in <module>
# del s[4]
#AttributeError: ArithmeticSequence instance has no attribute '__delitem__'
#print s["four"]
#Traceback (most recent call last):
# File "tta.py", line 57, in <module>
# s["four"]
# File "tta.py", line 27, in __getitem__
# checkIndex(key)
# File "tta.py", line 7, in checkIndex
# if not isinstance(key, (int, long)): raise TypeError
#TypeError
#print s[-42]
#Traceback (most recent call last):
# File "tta.py", line 67, in <module>
# print s[-42]
# File "tta.py", line 27, in __getitem__
# checkIndex(key)
# File "tta.py", line 8, in checkIndex
# if key<0: raise IndexError
#IndexError
#9.3.2 对列表, 字典和字符串进行子类化
>>> class CounterList(list):
... def __init__(self, *args):
... super(CounterList, self).__init__(*args)
... self.counter = 0
... def __getitem__(self, index):
... self.counter += 1
... return super(CounterList, self).__getitem__(index)
...
>>> c1 = CounterList(range(10))
>>> c1
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> c1.reverse()
>>> c1
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
>>> del c1[3:6]
>>> c1
[9, 8, 7, 3, 2, 1, 0]
>>> c1.counter
0
>>> c1[4] + c1[2]
9
>>> c1.counter
2
#9.4更多魔力 http://www.python.org/doc/ref/specialnames.html
#9.5 属性
>>> 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
...
>>> r = Rectangle()
>>> r.width=10
>>> r.height=5
>>> r.getSize()
(10, 5)
>>> r.setSize(150, 100)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: setSize() takes exactly 2 arguments (3 given)
>>> r.setSize((150, 100))
>>> r.width
150
#9.5.1 property 函数
#幸好, Python能隐藏访问器方法, 让所有特性看起来一样. 这些通过访问器定义的特性被称为属性
__metaclass__ = type
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
print r.size
r.size = 150, 100
print r.width
#python my.py
#(10, 5)
#150
#9.5.2 静态方法和类成员方法
__metaclass__ = type
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)
MyClass.smeth()
MyClass.cmeth()
#python ttb.py
#This is a static method
#This is a class method of <class '__main__.MyClass'>
__metaclass__ = type
class MyClass:
@staticmethod
def smeth():
print 'This is a static method'
@classmethod
def cmeth(cls):
print 'This is a class method of', cls
MyClass.smeth()
MyClass.cmeth()
#python ttc.py
#This is a static method
#This is a class method of <class '__main__.MyClass'>
#9.5.3 __getattr__, __setattr__, __delattr__
#__getattribute__(self, name)
#__getattr__(self, name)
#__setattr__(self, name)
#__delattr__(self, name)
class Rectangle:
def __init__(self):
self.width=0
self.height=0
def __setattr__(self, name, value):
if name == 'size':
self.width, self.height = size
else:
self.__dict__[name] = value
def __getattr__(self, name):
if name == 'size':
return self.width, self.height
else:
raise AttributeError
#9.6 迭代器
#9.6.1 迭代器规则
#__iter__方法返回一个迭代器(iterator), 所谓的迭代器就是具有next方法的对象. 在调用next方法时, 迭代器会返回它的下一个值.
#如果next方法被调用, 但迭代器没有值可以返回, 就会引发一个StopIteration异常
>>> 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:
... if f > 1000:
... print f
... break
...
1597
#内建函数iter可以从可迭代的对象中获得迭代器
>>> it = iter([1,2,3])
>>> it.next()
1
>>> it.next()
2
#9.6.2 从迭代器得到序列
>>> class TestIterator:
... value = 0
... def next(self):
... self.value += 1
... if self.value > 10: raise StopIteration
... return self.value
... def __iter__(self):
... return self
...
>>> ti = TestIterator()
>>> list(ti)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
#9.7 生成器
#9.7.1 创建生成器
>>> nested = [[1,2],[3,4],[5]]
>>> def flatten(nested):
... for sublist in nested:
... for element in sublist:
... yield element
...
>>> for num in flatten(nested):
... print num
...
1
2
3
4
5
>>> list(flatten(nested))
[1, 2, 3, 4, 5]
>>> g = ((i+2)**2 for i in range(2,27))
>>> g.next()
16
>>> sum(i**2 for i in range(10))
285
>>> sum(i for i in range(1,100))
4950
>>> sum(i for i in range(1,101))
5050
>>>
#9.7.2 递归生成器
def flatten(nested):
try:
for sublist in nested:
for element in flatten(sublist):
yield element
except TypeError:
yield nested
print list(flatten([[[1],2],3,4,[5,[6,7]],8]))
print list(flatten([[1,2],[3,4],[5]]))
#python tte.py
#[1, 2, 3, 4, 5, 6, 7, 8]
#[1, 2, 3, 4, 5]
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
print list(flatten(['foo', ['bar', ['baz']]]))
print list(flatten([[[1],2],3,4,[5,[6,7]],8]))
print list(flatten([[1,2],[3,4],[5]]))
#['foo', 'bar', 'baz']
#[1, 2, 3, 4, 5, 6, 7, 8]
#[1, 2, 3, 4, 5]
#9.7.3 通用生成器
>>> def simple_generator():
... yield 1
...
>>> simple_generator()
<generator object simple_generator at 0x00BBD418>
>>> simple_generator
<function simple_generator at 0x00BB2870>
#9.7.4 生成器方法
def repeater(value):
while True:
new = (yield value)
if new is not None: value = new
r = repeater(42)
print r.next()
print r.send("Hello, world!")
#42
#Hello, world!
#9.7.5 模拟生成器
def flatten(nested):
result = []
try:
# don't iterate on strings
try: nested + ''
except TypeError: pass
else: raise TypeError
for sublist in nested:
for element in flatten(sublist):
result.append(element)
except TypeError:
result.append(nested)
return result
print list(flatten(['foo', ['bar', ['baz']]]))
print list(flatten([[[1],2],3,4,[5,[6,7]],8]))
print list(flatten([[1,2],[3,4],[5]]))
#['foo', 'bar', 'baz']
#[1, 2, 3, 4, 5, 6, 7, 8]
#[1, 2, 3, 4, 5]
#9.8 八皇后问题
#9.8.1 生成器和回溯
#9.8.2 问题
#9.8.3 状态表示
#9.8.4 寻找冲突
#9.8.5 基本情况
#9.8.6 需要递归的情况
#9.8.7 助手函数
# coding = utf-8
#state[0]==3, 表示在第1行的皇后是在第4列
#参数nextX代表下一个皇后的水平位置(x坐标或列), nextY代表垂直位置(y坐标或行)
def conflict(state, nextX):
nextY = len(state)
for i in range(nextY):
# 如果下一个皇后和正在被考虑的当前皇后的水平距离为0(列相同)或者等于垂直距离(在一条对角线上)就返回True,否则就返回False
if abs(state[i]-nextX) in (0, nextY-i):
return True
return False
def queens(num, state):
if len(state) == num - 1:
for pos in range(num):
if not conflict(state, pos):
yield pos
print list(queens(4, (1,3,0)))
#[2]
def queens(num, state):
if len(state) == num - 1:
for pos in range(num):
if not conflict(state, pos):
yield pos
else:
for pos in range(num):
if not conflict(state, pos):
for result in queens(num, state + (pos,)):
yield(pos,) + result
def queens(num=8, state=()):
for pos in range(num):
if not conflict(state, pos):
if len(state) == num - 1:
yield(pos,)
else:
for result in queens(num, state + (pos,)):
yield (pos,) + result
print list(queens(3))
#[]
print list(queens(4))
#[(1, 3, 0, 2), (2, 0, 3, 1)]
for solution in queens(8):
print solution
#[(1, 3, 0, 2), (2, 0, 3, 1)]
#(0, 4, 7, 5, 2, 6, 1, 3)
#(0, 5, 7, 2, 6, 3, 1, 4)
#(0, 6, 3, 5, 7, 1, 4, 2)
#...
#(7, 3, 0, 2, 5, 1, 6, 4)
print len(list(queens(8)))
#92
def prettyprint(solution):
def line(pos, length=len(solution)):
return '. '*(pos) + 'X ' + '. '*(length-pos-1)
for pos in solution:
print line(pos)
import random
prettyprint(random.choice(list(queens(8))))
#. . X . . . . .
#. . . . . X . .
#. X . . . . . .
#. . . . . . X .
#X . . . . . . .
#. . . X . . . .
#. . . . . . . X
#. . . . X . . .
print ''
prettyprint(random.choice(list(queens(4))))
#. . X .
#X . . .
#. . . X
#. X . .
#9.9 小结
#旧式类和新式类 魔法方法 构造器 重写 序列和映射 迭代器 生成器 八皇后问题
#新函数
#iter(obj) 从一个可迭代对象得到迭代器
#property(fget, fset, fdel, doc) 返回一个属性, 所有的参数都是可选的
#super(class, obj) 返回一个类的超类的绑定实例
分享到:
相关推荐
在Python编程语言中,新式类(new-style classes)与旧式类(old-style classes)的概念主要存在于Python 2.x版本。新式类引入了一些重要的特性,如属性、super函数等,这些特性使得面向对象编程更为强大。在Python ...
第9章 魔法方法、属性和迭代器 第10章 充电时刻 第11章 文件和素材 第12章 图形用户界面 第13章 数据库支持 第14章 网络编程 第15章 Python和万维网 第16章 测试 第17章 扩展Python 第18章 程序打包 第19...
《Python基础教程》第三版源代码是一份详细的学习资源,涵盖了Python编程的多个核心概念和实践技巧。这个源代码集合包括了从基础语法到高级特性的各种示例,旨在帮助初学者逐步掌握Python编程。 在Python的基础部分...
然后循序渐进地介绍了一些相对高级的主题,包括抽象、异常、魔法方法、属性、迭代器。此后探讨了如何将Python与数据库、网络、C语言等工具结合使用,从而发挥出Python的强大功能,同时介绍了Python程序测试、打包、...
《Python基础教程第二版》是针对初学者的一本经典教材,尤其适合那些对Python 2.0版本感兴趣的读者。本书全面、深入地介绍了Python编程语言的基础概念和语法,旨在帮助读者掌握这一强大而灵活的编程工具。以下是根据...
**Python基础教程第三版概述** Python是一种高级编程语言,以其简洁、易读的语法和强大的功能而闻名。作为初学者入门编程或者专业人士增强技能的工具,Python基础教程第三版是学习这一语言的理想资源。该高清版教程...
然后循序渐进地介绍了一些相对高级的主题,包括抽象、异常、魔法方法、属性、迭代器。此后探讨了如何将Python与数据库、网络、C语言等工具结合使用,从而发挥出Python的强大功能,同时介绍了Python程序测试、打包、...
然后循序渐进地介绍了一些相对高级的主题,包括抽象、异常、魔法方法、属性、迭代器;此后探讨了如何将Python与数据库、网络、C语言等工具结合使用,从而发挥出Python的强大功能,同时介绍了Python程序测试、打包、...
然后循序渐进地介绍了一些相对高级的主题,包括抽象、异常、魔法方法、属性、迭代器。此后探讨了如何将Python 与数据库、网络、C 语言等工具结合使用,从而发挥出Python 的强大功能,同时介绍了Python 程序测试、...
《Python基础教程(第2版)》是一本全面介绍Python编程的指南,适合初学者入门。Python作为一种解释型、面向对象、动态数据类型的高级程序设计语言,因其简洁的语法和强大的功能而广受欢迎。该书分为基础篇和高级篇...
Python是世界上最受欢迎的编程语言之一,尤其适合初学者入门。在Python编程中,了解脚本第一行的作用至关重要,特别是对于那些在Linux或Unix系统中工作的人来说。本文将深入讲解Python脚本首行的含义,以及如何正确...
"Python基础教程配套源码"是一份旨在帮助初学者深入理解Python编程原理和实践的资源。这个压缩包可能包含了与Python基础教程相关的各种示例代码、练习和项目,帮助学习者通过实际操作来巩固理论知识。 在Python的...
迭代器和生成器是Python编程中的重要概念,特别是在处理大量数据或进行高效内存管理时,它们的优势尤为明显。本文将详细讲解这两个概念及其在Python语言中的应用。 **迭代器** 迭代器是Python中访问集合元素的一种...
此外,Python的迭代器和生成器为处理大数据提供了高效的方法。 最后,Python的单元测试和调试技巧也是提升代码质量的重要手段。通过学习如何编写测试用例、使用断言以及调试工具,你可以确保代码的正确性和稳定性。...
Iterable对象和Iterator对象是Python中的两个基本概念,Iterable对象是可以被迭代的对象,而Iterator对象是Iterable对象的迭代器。 在Python中,Iterable对象可以通过`__iter__()`方法返回一个Iterator对象,而...
python基础教程第三版前9章的内容,学习过程中绘制了思维导图,导图工具软件是MindMaster,大于6.5版本的都可以打开
然后循序渐进地介绍了一些相对高级的主题,包括抽象、异常、魔法方法、属性、迭代器;此后探讨了如何将Python与数据库、网络、C语言等工具结合使用,从而发挥出Python的强大功能,同时介绍了Python程序测试、打包、...
Python入门基础教程全套.PPT,Python入门基础教程全套.PPT,Python入门基础教程全套.PPT,Python入门基础教程全套.PPT,Python入门基础教程全套.PPT,Python入门基础教程全套.PPT,Python入门基础教程全套.PPT,...
Python全套教程 Python基础python基础课代码+文档2023最新教程【樵夫教你学Python】Python全套教程 Python基础python基础课代码+文档2023最新教程【樵夫教你学Python】Python全套教程 Python基础python基础课代码+...