# 特殊方法 **Python** 使用 `__` 开头的名字来定义特殊的方法和属性,它们有: * `__init__()` * `__repr__()` * `__str__()` * `__call__()` * `__iter__()` * `__add__()` * `__sub__()` * `__mul__()` * `__rmul__()` * `__class__` * `__name__` ## 构造方法 `__init__()` 之前说到,在产生对象之后,我们可以向对象中添加属性。事实上,还可以通过构造方法,在构造对象的时候直接添加属性: In [1]: ``` class Leaf(object): """ A leaf falling in the woods. """ def __init__(self, color='green'): self.color = color ``` 默认属性值: In [2]: ``` leaf1 = Leaf() print leaf1.color ``` ``` green ``` 传入有参数的值: In [3]: ``` leaf2 = Leaf('orange') print leaf2.color ``` ``` orange ``` 回到森林的例子: In [4]: ``` import numpy as np class Forest(object): """ Forest can grow trees which eventually die.""" def __init__(self): self.trees = np.zeros((150,150), dtype=bool) self.fires = np.zeros((150,150), dtype=bool) ``` 我们在构造方法中定义了两个属性 `trees` 和 `fires`: In [5]: ``` forest = Forest() forest.trees ``` Out[5]: ``` array([[False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False], ..., [False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False]], dtype=bool) ``` In [6]: ``` forest.fires ``` Out[6]: ``` array([[False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False], ..., [False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False]], dtype=bool) ``` 修改属性的值: In [7]: ``` forest.trees[0,0]=True forest.trees ``` Out[7]: ``` array([[ True, False, False, ..., False, False, False], [False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False], ..., [False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False]], dtype=bool) ``` 改变它的属性值不会影响其他对象的属性值: In [8]: ``` forest2 = Forest() forest2.trees ``` Out[8]: ``` array([[False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False], ..., [False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False], [False, False, False, ..., False, False, False]], dtype=bool) ``` 事实上,`__new__()` 才是真正产生新对象的方法,`__init__()` 只是对对象进行了初始化,所以: ``` leaf = Leaf() ``` 相当于 ``` my_new_leaf = Leaf.__new__(Leaf) Leaf.__init__(my_new_leaf) leaf = my_new_leaf ``` ## 表示方法 `__repr__()` 和 `__str__()` In [9]: ``` class Leaf(object): """ A leaf falling in the woods. """ def __init__(self, color='green'): self.color = color def __str__(self): "This is the string that is printed." return "A {} leaf".format(self.color) def __repr__(self): "This string recreates the object." return "{}(color='{}')".format(self.__class__.__name__, self.color) ``` `__str__()` 是使用 `print` 函数显示的结果: In [10]: ``` leaf = Leaf() print leaf ``` ``` A green leaf ``` `__repr__()` 返回的是不使用 `print` 方法的结果: In [11]: ``` leaf ``` Out[11]: ``` Leaf(color='green') ``` 回到森林的例子: In [12]: ``` import numpy as np class Forest(object): """ Forest can grow trees which eventually die.""" def __init__(self, size=(150,150)): self.size = size self.trees = np.zeros(self.size, dtype=bool) self.fires = np.zeros((self.size), dtype=bool) def __repr__(self): my_repr = "{}(size={})".format(self.__class__.__name__, self.size) return my_repr def __str__(self): return self.__class__.__name__ ``` In [13]: ``` forest = Forest() ``` `__str__()` 方法: In [14]: ``` print forest ``` ``` Forest ``` `__repr__()` 方法: In [15]: ``` forest ``` Out[15]: ``` Forest(size=(150, 150)) ``` `__name__` 和 `__class__` 为特殊的属性: In [16]: ``` forest.__class__ ``` Out[16]: ``` __main__.Forest ``` In [17]: ``` forest.__class__.__name__ ``` Out[17]: ``` 'Forest' ```