笔记:魔法方法
魔法方法
构造函数
__init__
,类的初始化方法。构造函数不同于普通方法的地方在于。对象创建后会自动调用。
创建一个构造函数
class FooBar():
def __init__(self):
self.somevar = 42
f = FooBar()
f.somevar # 42
析构函数
__del__
,这个方法在对象被销毁(垃圾被收集)前调用,但是鉴于无法知道准确的调用时间,尽可能不使用__del__
。
基本的序列和映射协议
_len_(self)
这个方法返回集合包含的项数,对序列来说为元素个数,对映射来说为键-值对数。如果__len__
返回零(且没有实现__nonzero__
),对象在布尔上下文中将视为假(就像空的元组,字符串,列表,字典一样)。
_getitem_(self, key)
这个方法返回指定键和相关联的值。
_setitem_(self, key, value)
这个方法以与键相关联的方式存储值。以便以后可以使用__getitem__
来获取。
_delitem_(self, key)
这个方法在对对象的组成部分使用__del__
语句时被调用,删除与key相关联的值。
创建一个无穷序列
def check_index(key):
"""
指定的键是否是可接受的索引?
键必须是非负整数,如果不是,将引发TypeError异常。
如果是负数,将引发IndexError异常(因为这个序列的长度是无穷的)。
"""
if not isinstance(key, int): raise TypeError
if key < 0: raise IndexError
class AritmeticSequence():
def __init__(self, start=0, step=0):
"""[summary]
初始化这个算数序列
Keyword Arguments:
start {number} -- 序列中的第一个值 (default: {0})
step {number} -- 两个相邻值的差 (default: {0})
changed {dict} -- 一个字典,包含用户修改后的值
"""
self.start = start # 存储起始值
self.step = step # 存储步长值
self.changed = {} # 没有任何元素被修改
def __getitem__(self, key):
"""
从算数序列中获取一个元素
"""
check_index(key)
try: return self.changed[key] # 修改过?
except KeyError: # 如果没有修改过
return self.start + key * self.step # 就计算元素的值
def __setitem__(self, key, value):
"""
修改算数序列中的元素
"""
check_index(key)
self.changed[key] = value
s = AritmeticSequence()
for i in range(10):
print(s[i], end=" ")
# 1 3 5 7 9 11 13 15 17 19
迭代器
__iter__
方法返回一个迭代器,它包含__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:
print(f, end=" ")
if f > 100:
break
这个迭代器实现了方法__iter__
,这个方法返回迭代器本身,这样迭代器就可直接用于for循环中。
实现了方法
__iter__
的对象是可迭代的,而实现了__next__
方法的对象是迭代器。