Files
ailearning/docs/da/106.md
2020-10-19 21:08:55 +08:00

266 lines
3.9 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 属性
## 只读属性
只读属性,顾名思义,指的是只可读不可写的属性,之前我们定义的属性都是可读可写的,对于只读属性,我们需要使用 `@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)
```