08.09 super() 函数
super() 函数
super(CurrentClassName, instance)
返回该类实例对应的父类对象。
1class Leaf(object):
2 def __init__(self, color="green"):
3 self.color = color
4 def fall(self):
5 print "Splat!"
6
7class MapleLeaf(Leaf):
8 def change_color(self):
9 if self.color == "green":
10 self.color = "red"
11 def fall(self):
12 self.change_color()
13 super(MapleLeaf, self).fall()
这里,我们先改变树叶的颜色,然后再找到这个实例对应的父类,并调用父类的 fall() 方法:
1mleaf = MapleLeaf()
2
3print mleaf.color
4mleaf.fall()
5print mleaf.color
green
Splat!
red
回到我们的森林例子,这里我们将森林 Forest 作为父类,并定义一个子类 BurnableForest:
1import numpy as np
2
3class Forest(object):
4 """ Forest can grow trees which eventually die."""
5 def __init__(self, size=(150,150), p_sapling=0.0025):
6 self.size = size
7 self.trees = np.zeros(self.size, dtype=bool)
8 self.p_sapling = p_sapling
9
10 def __repr__(self):
11 my_repr = "{}(size={})".format(self.__class__.__name__, self.size)
12 return my_repr
13
14 def __str__(self):
15 return self.__class__.__name__
16
17 @property
18 def num_cells(self):
19 """Number of cells available for growing trees"""
20 return np.prod(self.size)
21
22 @property
23 def tree_fraction(self):
24 """
25 Fraction of trees
26 """
27 num_trees = self.trees.sum()
28 return float(num_trees) / self.num_cells
29
30 def _rand_bool(self, p):
31 """
32 Random boolean distributed according to p, less than p will be True
33 """
34 return np.random.uniform(size=self.trees.shape) < p
35
36 def grow_trees(self):
37 """
38 Growing trees.
39 """
40 growth_sites = self._rand_bool(self.p_sapling)
41 self.trees[growth_sites] = True
42
43 def advance_one_step(self):
44 """
45 Advance one step
46 """
47 self.grow_trees()
- 将与燃烧相关的属性都被转移到了子类中去。
- 修改两类的构造方法,将闪电概率放到子类的构造方法上,同时在子类的构造方法中,用
super调用父类的构造方法。 - 修改
advance_one_step(),父类中只进行生长,在子类中用super调用父类的advance_one_step()方法,并添加燃烧的部分。
1class BurnableForest(Forest):
2 """
3 Burnable forest support fires
4 """
5 def __init__(self, p_lightning=5.0e-6, **kwargs):
6 super(BurnableForest, self).__init__(**kwargs)
7 self.p_lightning = p_lightning
8 self.fires = np.zeros((self.size), dtype=bool)
9
10 def advance_one_step(self):
11 """
12 Advance one step
13 """
14 super(BurnableForest, self).advance_one_step()
15 self.start_fires()
16 self.burn_trees()
17
18 @property
19 def fire_fraction(self):
20 """
21 Fraction of fires
22 """
23 num_fires = self.fires.sum()
24 return float(num_fires) / self.num_cells
25
26 def start_fires(self):
27 """
28 Start of fire.
29 """
30 lightning_strikes = (self._rand_bool(self.p_lightning) &
31 self.trees)
32 self.fires[lightning_strikes] = True
33
34 def burn_trees(self):
35 """
36 Burn trees.
37 """
38 fires = np.zeros((self.size[0] + 2, self.size[1] + 2), dtype=bool)
39 fires[1:-1, 1:-1] = self.fires
40 north = fires[:-2, 1:-1]
41 south = fires[2:, 1:-1]
42 east = fires[1:-1, :-2]
43 west = fires[1:-1, 2:]
44 new_fires = (north | south | east | west) & self.trees
45 self.trees[self.fires] = False
46 self.fires = new_fires
测试父类:
1forest = Forest()
2
3forest.grow_trees()
4
5print forest.tree_fraction
0.00284444444444
测试子类:
1burnable_forest = BurnableForest()
调用自己和父类的方法:
1burnable_forest.grow_trees()
2burnable_forest.start_fires()
3burnable_forest.burn_trees()
4print burnable_forest.tree_fraction
0.00235555555556
查看变化:
1import matplotlib.pyplot as plt
2
3%matplotlib inline
4
5forest = Forest()
6forest2 = BurnableForest()
7
8tree_fractions = []
9
10for i in range(2500):
11 forest.advance_one_step()
12 forest2.advance_one_step()
13 tree_fractions.append((forest.tree_fraction, forest2.tree_fraction))
14
15plt.plot(tree_fractions)
16
17plt.show()
__str__ 和 __repr__ 中 self.__class__ 会根据类型不同而不同:
1forest
Forest(size=(150, 150))
1forest2
BurnableForest(size=(150, 150))
1print forest
Forest
1print forest2
BurnableForest