python 学习笔记 六 类
一个简单的类
class MyClass: """A simple example class""" i = 12345 def f(self): return 'hello world'
几点:
1. 在类前面加上__metaclass__ = type表示使用新式类
2. Pyyhon不直接支持私有特性, 为了让方法或特性变为私有(只能在类内部使用, 从外部无法访问), 可以在名字前面加双下划线: __f()
3. 一个习惯: 如果不需要使用这些方法, 而又想让其他对象不要访问这些内部数据, 可以使用单下划线
关于第二点要注意的是, 在类的内部定义中, 所有双下划线开始的名字都被"翻译"成前面加上单下划线和类名的形式, _classname__f(), 在了解这些后, 实际上还是可以从外部访问这些私有方法, 尽管不应该这样做:object._classname__f(), 总是, 确保其他人不会访问方法和特性是不可能的, 但是这种双下划线名是他们不应该访问这些函数或特性的强有力信号.
继承(Inheritance)
单继承:
class DerivedClassName(BaseClassName): <statement-1> . . . <statement-N>
多继承:
class DerivedClassName(Base1, Base2, Base3): <statement-1> . . . <statement-N>
构造方法
构造方法被命名为__init__, 在对象被创建后立即自动调用
def __init__(self): self.data = []
考虑一个问题, 定义一个鸟类:
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): self.sound = 'Squawk!' def sing(self): print self.sound
这个类继承了Bird类, 继承了eat方法, 但如果调用这个方法会发生AttributeError错误, 原因是: 在SongBird中, 构造方法被重写, 新的构造方法没有初始化'hungry'特性的代码. 为了达到预期效果, SongBird的构造方法必须调用基类Bird的构造方法来确保进行基本的初始化, 有俩种方法:
1. 调用未绑定的超类方法
class SongBird(Bird): def __init__(self): Bird.__initi(self) self.sound = 'Squawk!' def sing(self): print self.sound
在构造方法中加了一行代码,
2. 使用super函数
只能在新式类中使用,将第一种方法中多出的一行改为:
super(SongBird, self).__init__()
类的属性
要知道一个类具有那些属性可以使用2种方法:
1.dir()内建函数: dir(classname)
2.__dict__: classname.__dict__
迭代器
你可能注意到, 大部分容器都是可以通过for遍历:
for element in [1, 2, 3]: print element for element in (1, 2, 3): print element for key in {'one':1, 'two':2}: print key for char in "123": print char for line in open("myfile.txt"): print line,
使用这种迭代方式简洁, 精确, 方便, Python中使用迭代器是非常普遍的. 背后的机制是: for循环调用容器对象的iter()函数, 函数返回一个定义了next()方法的容器对象, next()方法每次从容器中获取一个元素, 当没有更多元素时, next()方法引起一个StopIteration()异常, 这个异常告诉for循环终止迭代. 看这个例子:
>>> s = 'abc' >>> it = iter(s) >>> it <iterator object at 0x00A1DB50> >>> it.next() 'a' >>> it.next() 'b' >>> it.next() 'c' >>> it.next() Traceback (most recent call last): File "<stdin>", line 1, in ? it.next() StopIteration
知道了迭代器规则背后的机制后, 为类添加迭代器是很容易的. 定义一个__iter__()方法, 它返回具有next()方法的对象, 如果类定义了next()方法, 那么__iter__()就返回self.
class Reverse: """Iterator for looping over a sequence backwards.""" def __init__(self, data): self.data = data self.index = len(data) def __iter__(self): return self def next(self): if self.index == 0: raise StopIteration self.index = self.index - 1 return self.data[self.index]
>>> rev = Reverse('spam') >>> iter(rev) <__main__.Reverse object at 0x00A1DB50> >>> for char in rev: ... print char ... m a p s
生成器
生成器函数(或方法)是包含了关键字yield的函数(或方法). 当被调用时, 生成器返回一个生成器.