特性
Python使用异常对象来表示异常状态,并在遇到错误时引发异常
构造函数
重写构造函数,要调用父类构造方法
class Bird:
def __init__(self):
self.hungry = True
def eat(self):
if self.hungry:
print('Aaaah ...')
self.hungry = False
else:
print('No, thanks!')
方式1
class SongBird(Bird):
def __init__(self):
Bird.__init__(self) #重点
self.sound = 'Squawk!'
def sing(self):
print(self.sound)
方式2
class SongBird(Bird):
def __init__(self):
super().__init__() #推荐使用
self.sound = 'Squawk!'
def sing(self):
print(self.sound)
元素访问
基本的序列和映射协议
基本的序列和映射协议
def check_index(key):
"""
指定的键是否是可接受的索引?
键必须是非负整数,才是可接受的。如果不是整数,
将引发TypeError异常;如果是负数,将引发Index
Error异常(因为这个序列的长度是无穷的)
"""
if not isinstance(key, int): raise TypeError
if key < 0: raise IndexError
class ArithmeticSequence:
def __init__(self, start=0, step=1):
"""
初始化这个算术序列
start -序列中的第一个值
step -两个相邻值的差
changed -一个字典,包含用户修改后的值
"""
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 # 存储修改后的值
从 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)
property&类方法&静态方法
函数 property
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.width = 10
>>> r.height = 5
>>> r.size
(10, 5)
>>> r.size = 150, 100
>>> r
静态方法和类方法
#方式1
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)
#方式2
class MyClass:
@staticmethod
def smeth():
print('This is a static method')
@classmethod
def cmeth(cls):
print('This is a class method of', cls)
getattr 、 setattr 等方法
class Rectangle:
def __init__ (self):
self.width = 0
self.height = 0
def __setattr__(self, name, value):
if name == 'size':
self.width, self.height = value
else:
self. __dict__[name] = value #不执行常规属性赋值,是因为旨在避免再次调用 __setattr__ ,进而导致无限循环
def __getattr__(self, name):
if name == 'size':
return self.width, self.height
else:
raise AttributeError()
编写方法 __setattr__ 时需要避开无限循环陷阱,编写 __getattribute__ 时亦如此。
由于它拦截对所有属性的访问(在新式类中),因此将拦截对 __dict__ 的访问!
在 __getattribute__ 中访问当前实例的属性时,唯一安全的方式是使用超类的方法 __getattribute__ (使用 super )
迭代器
实现了方法 __iter__ 的对象是 可迭代的,而实现了方法 __next__ 的对象是 迭代器
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
通过对可迭代对象调用内置函数 iter ,可获得一个迭代器。
>>> it = iter([1, 2, 3])
>>> next(it)
1
>>> next(it)
2
生成器
包含 yield 语句的函数都被称为生成器
def flatten(nested):
for sublist in nested:
for element in sublist:
yield element
>>> nested = [[1, 2], [3, 4], [5]]
>>> 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))
>>> next(g)
16
生成器由两个单独的部分组成:生成器的函数和生成器的迭代器。生成器的函数是由 def 语句定义的,其中包含 yield 。
生成器的迭代器是这个函数返回的结果。用不太准确的话说,这两个实体通常被视为一个,通称为生成器。
>>> def simple_generator():
yield 1
...
>>> simple_generator
<function simple_generator at 153b44>
>>> simple_generator()
<generator object at 1510b0>
生成器方法
仅当生成器被挂起(即遇到第一个 yield )后,使用 send (而不是 next )才有意义
如果一定要在生成器刚启动时对其调用方法 send ,可向它传递参数 None
def repeater(value):
while True:
new = (yield value)
if new is not None: value = new
>>> r = repeater(42)
>>> next(r)
42
>>> r.send("Hello, world!")
"Hello, world!"