mirror of
https://github.com/apachecn/ailearning.git
synced 2026-02-11 14:26:04 +08:00
266 lines
3.9 KiB
Markdown
266 lines
3.9 KiB
Markdown
# 属性
|
||
|
||
## 只读属性
|
||
|
||
只读属性,顾名思义,指的是只可读不可写的属性,之前我们定义的属性都是可读可写的,对于只读属性,我们需要使用 `@property` 修饰符来得到:
|
||
|
||
In [1]:
|
||
|
||
```py
|
||
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]:
|
||
|
||
```py
|
||
leaf = Leaf(200)
|
||
|
||
print leaf.mass_oz
|
||
|
||
```
|
||
|
||
```py
|
||
0.00706
|
||
|
||
```
|
||
|
||
可以修改 `mass_mg` 属性来改变 `mass_oz`:
|
||
|
||
In [3]:
|
||
|
||
```py
|
||
leaf.mass_mg = 150
|
||
|
||
print leaf.mass_oz
|
||
|
||
```
|
||
|
||
```py
|
||
0.005295
|
||
|
||
```
|
||
|
||
是属性不是方法:
|
||
|
||
In [4]:
|
||
|
||
```py
|
||
leaf.mass_oz()
|
||
|
||
```
|
||
|
||
```py
|
||
---------------------------------------------------------------------------
|
||
TypeError Traceback (most recent call last)
|
||
<ipython-input-4-aac6717ebc82> in <module>()
|
||
----> 1 leaf.mass_oz()
|
||
|
||
TypeError: 'float' object is not callable
|
||
```
|
||
|
||
而且是只读属性,不可写:
|
||
|
||
In [5]:
|
||
|
||
```py
|
||
leaf.mass_oz = 0.001
|
||
|
||
```
|
||
|
||
```py
|
||
---------------------------------------------------------------------------
|
||
AttributeError Traceback (most recent call last)
|
||
<ipython-input-5-d232052cd2dc> in <module>()
|
||
----> 1 leaf.mass_oz = 0.001
|
||
|
||
AttributeError: can't set attribute
|
||
```
|
||
|
||
回到 `forest` 的例子,我们希望加入几个只读属性:
|
||
|
||
In [6]:
|
||
|
||
```py
|
||
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]:
|
||
|
||
```py
|
||
forest = Forest()
|
||
|
||
forest.num_cells
|
||
|
||
```
|
||
|
||
Out[7]:
|
||
|
||
```py
|
||
22500
|
||
```
|
||
|
||
生成一个较小的森林:
|
||
|
||
In [8]:
|
||
|
||
```py
|
||
small_forest = Forest((10, 10))
|
||
small_forest.num_cells
|
||
|
||
```
|
||
|
||
Out[8]:
|
||
|
||
```py
|
||
100
|
||
```
|
||
|
||
初始状态下,树和火灾的比例都是 0:
|
||
|
||
In [9]:
|
||
|
||
```py
|
||
small_forest.tree_fraction
|
||
|
||
```
|
||
|
||
Out[9]:
|
||
|
||
```py
|
||
0.0
|
||
```
|
||
|
||
In [10]:
|
||
|
||
```py
|
||
small_forest.fire_fraction
|
||
|
||
```
|
||
|
||
Out[10]:
|
||
|
||
```py
|
||
0.0
|
||
```
|
||
|
||
## 可读写的属性
|
||
|
||
对于 `@property` 生成的只读属性,我们可以使用相应的 `@attr.setter` 修饰符来使得这个属性变成可写的:
|
||
|
||
In [11]:
|
||
|
||
```py
|
||
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]:
|
||
|
||
```py
|
||
leaf = Leaf(200)
|
||
print leaf.mass_oz
|
||
|
||
leaf.mass_mg = 150
|
||
print leaf.mass_oz
|
||
|
||
```
|
||
|
||
```py
|
||
0.00706
|
||
0.005295
|
||
|
||
```
|
||
|
||
修改 `mass_oz` 属性:
|
||
|
||
In [13]:
|
||
|
||
```py
|
||
leaf.mass_oz = 0.01
|
||
print leaf.mass_mg
|
||
|
||
```
|
||
|
||
```py
|
||
283.28611898
|
||
|
||
```
|
||
|
||
一个等价的替代如下:
|
||
|
||
```py
|
||
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)
|
||
|
||
``` |