什麼是 property特性
- property裝飾器用於將被裝飾的方法偽裝成一個資料屬性,在使用時可以不用加括號而直接使用
例一:BMI指數(bmi是計算而來的,但很明顯它聽起來像是一個屬性而非方法,如果我們將其做成一個屬性,更便於理解)
成人的BMI數值:
- 過輕:低於18.5
- 正常:18.5-23.9
- 過重:24-27
- 肥胖:28-32
- 非常肥胖,高於32
體質指數(BMI)= 體重(kg)÷ 身高^2(m)
- e.g:70kg÷(1.75×1.75)=22.86
class People:
def __init__(self, name, weight, height):
self.name = name
self.weight = weight
self.height = height
def bmi(self):
return self.weight / (self.height**2)
peo1 = People('nick', 70, 1.8)
print(peo1.bmi())
21.604938271604937
property特性單獨使用
class People:
def __init__(self, name, weight, height):
self.name = name
self.weight = weight
self.height = height
@property
def bmi(self):
return self.weight / (self.height**2)
peo1 = People('nick', 70, 1.8)
print(peo1.bmi)
21.604938271604937
peo1.height = 1.85
print(peo1.bmi)
20.45288531775018
property特性+類的封裝
class People:
def __init__(self, name):
self.__name = name
@property # 檢視obj.name
def name(self):
return '<名字是:%s>' % self.__name
peo1 = People('nick')
print(peo1.name)
<名字是:nick>
try:
peo1.name = 'EGON'
except Exception as e:
print(e)
can't set attribute
setter/deleter裝飾器
- 控制屬性的修改和刪除
class People:
def __init__(self, name):
self.__name = name
@property # 檢視 obj.name
def name(self):
return '<名字是:%s>' % self.__name
@name.setter # 修改 obj.name=值 觸發
def name(self, name):
if type(name) is not str:
raise TypeError('名字必須是str型別傻叉')
self.__name = name
@name.deleter # 刪除 del obj.name 觸發
def name(self):
# raise PermissionError('不讓刪')
print('不讓刪除傻叉')
# del self.__name
peo1 = People('nick')
print(peo1.name)
<名字是:nick>
try:
peo1.name = 10
except Exception as e:
print(e)
名字必須是str型別傻叉
peo1.name = 'Nick'
print(peo1.name)
<名字是:Nick>
del peo1.name
不讓刪除傻叉
property的古老用法(瞭解)
class People:
def __init__(self, name):
self.__name = name
def tell_name(self):
return '<名字是:%s>' % self.__name
def set_name(self, name):
if type(name) is not str:
raise TypeError('名字必須是str型別傻叉')
self.__name = name
def del_name(self):
print('不讓刪除傻叉')
# 相當於新增了property、setter、deleter裝飾器(推薦使用裝飾器)
# 與property()方法內的函式名字無關,三個函式必須依次為列印、修改、刪除
name = property(tell_name, set_name, del_name)
peo1 = People('egon')
print(peo1.name)
<名字是:egon>
peo1.name = 'EGON'
print(peo1.name)
<名字是:EGON>
del peo1.name
不讓刪除傻叉
property特性練習
- 圓的周長和麵積
import math
class Circle:
def __init__(self, radius): # 圓的半徑radius
self.radius = radius
@property
def area(self):
return math.pi * self.radius**2 # 計算面積
@property
def perimeter(self):
return 2 * math.pi * self.radius # 計算周長
c = Circle(10)
print(c.radius)
10
print(c.area) # 可以向訪問資料屬性一樣去訪問area,會觸發一個函式的執行,動態計算出一個值
314.1592653589793
print(c.perimeter) # 同上
62.83185307179586