注意 py 中声明只有一个元素的元组的时候应该写成 t = (1,) 而不是 (1)。后者会被解释器解释为变量而非元组。
多继承
和 java 有着显著区别,python3 的类允许多继承。多继承带来了菱形问题(Diamond Problem):如果多个父类继承同一个基类,可能导致方法调用冲突。如下所示:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 
 | class A:def method(self):
 print("A")
 
 class B(A):
 def method(self):
 super().method()
 print("B")
 
 class C(A):
 def method(self):
 super().method()
 print("C")
 
 class D(B, C):
 def method(self):
 super().method()
 print("D")
 
 d = D()
 d.method()
 print(D.__mro__)
 
 | 
Python 3 使用 C3 线性化算法(MRO)解决冲突。在上面的例子中:
- 调用顺序:D → B → C → A(B 优先于 C,因为 class D(B, C) 里 B 在前)。
- 如果 B 没有 method(),则调用 C 的 method()。
上面的例子中 A 虽然被继承了 2 次,但是并不存在调用多次的问题。
多继承可以很方便实现 mix-in 模式。
slots
__slots__的目的是限制当前类所能拥有的属性,避免因为外部属性的操作导致类属性越来越难以管理。
| 12
 3
 4
 5
 6
 7
 8
 9
 
 | class Student(object):__slots__ = ('name', 'gender', 'score')
 def __init__(self, name, gender, score):
 self.name = name
 self.gender = gender
 self.score = score
 
 s = Student('Bob', 'male', 59)
 
 
 | 
call
__call__方法可以让一个类的实例像函数一样被调用。当实例后面加括号时,就会调用 __call__方法。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 
 | class Fib:def __call__(self, count = 10):
 res = []
 a, b = 0, 1
 for i in range(count):
 res.append(a)
 a, b = b, a + b
 return res
 
 f = Fib()
 print(f(10))
 
 | 
函数式编程
可以实现延迟计算:
| 12
 3
 4
 
 | def calc_sum(list_):def lazy_sum():
 return sum(list_)
 return lazy_sum
 
 | 
装饰器
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 
 | import time
 def performance(unit):
 def perf_decorator(f):
 def wrapper(*args, **kwargs):
 t1 = time.time()
 r = f(*args, **kwargs)
 t2 = time.time()
 t = (t2 - t1) * 1000 if unit == 'ms' else (t2 - t1)
 print('call {}() in {} {}'.format(f.__name__, t, unit))
 return r
 return wrapper
 return perf_decorator
 
 @performance('ms')
 
 def test(a):
 
 time.sleep(1)
 print('test', a)
 
 test(1)
 
 |