#!/usr/bin/env python # coding: utf-8 # # 属性 # ## 只读属性 # 只读属性,顾名思义,指的是只可读不可写的属性,之前我们定义的属性都是可读可写的,对于只读属性,我们需要使用 `@property` 修饰符来得到: # In[1]: class Leaf(object): def __init__(self, mass_mg): self.mass_mg = mass_mg # 这样 mass_oz 就变成属性了 @property def mass_oz(self): return self.mass_mg * 3.53e-5 # 这里 `mass_oz` 就是一个只读不写的属性(注意是属性不是方法),而 `mass_mg` 是可读写的属性: # In[2]: leaf = Leaf(200) print leaf.mass_oz # 可以修改 `mass_mg` 属性来改变 `mass_oz`: # In[3]: leaf.mass_mg = 150 print leaf.mass_oz # 是属性不是方法: # In[4]: leaf.mass_oz() # 而且是只读属性,不可写: # In[5]: leaf.mass_oz = 0.001 # 回到 `forest` 的例子,我们希望加入几个只读属性: # In[6]: 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__ @property def num_cells(self): """Number of cells available for growing trees""" return np.prod(self.size) @property def tree_fraction(self): """ Fraction of trees """ num_trees = self.trees.sum() return float(num_trees) / self.num_cells @property def fire_fraction(self): """ Fraction of fires """ num_fires = self.fires.sum() return float(num_fires) / self.num_cells # 查看属性: # In[7]: forest = Forest() forest.num_cells # 生成一个较小的森林: # In[8]: small_forest = Forest((10, 10)) small_forest.num_cells # 初始状态下,树和火灾的比例都是 0: # In[9]: small_forest.tree_fraction # In[10]: small_forest.fire_fraction # ## 可读写的属性 # 对于 `@property` 生成的只读属性,我们可以使用相应的 `@attr.setter` 修饰符来使得这个属性变成可写的: # In[11]: class Leaf(object): def __init__(self, mass_mg): self.mass_mg = mass_mg # 这样 mass_oz 就变成属性了 @property def mass_oz(self): return self.mass_mg * 3.53e-5 # 使用 mass_oz.setter 修饰符 @mass_oz.setter def mass_oz(self, m_oz): self.mass_mg = m_oz / 3.53e-5 # 测试: # In[12]: leaf = Leaf(200) print leaf.mass_oz leaf.mass_mg = 150 print leaf.mass_oz # 修改 `mass_oz` 属性: # In[13]: leaf.mass_oz = 0.01 print leaf.mass_mg # 一个等价的替代如下: # # ```python # class Leaf(object): # def __init__(self, mass_mg): # self.mass_mg = mass_mg # # def get_mass_oz(self): # return self.mass_mg * 3.53e-5 # # def set_mass_oz(self, m_oz): # self.mass_mg = m_oz / 3.53e-5 # # mass_oz = property(get_mass_oz, set_mass_oz) # ```