property是一種特殊的屬性,訪問它時會執行一段功能(函數)而後返回值。python
from math import pi class Circle: def __init__(self,r): self.r = r @property def perimeter(self): return 2*pi*self.r @property def area(self): return self.r**2*pi c1 = Circle(5) print(c1.area) # 圓的面積 print(c1.perimeter) # 圓的周長
class BMI: def __init__(self,weight,height): self.weight=weight self.height=height @property def bmi(self): return self.weight/self.height**2 gaoya=BMI(47,1.60) print(gaoya.bmi)
將一個類的函數定義成特性之後,對象再去使用的時候obj.name,根本沒法察覺本身的name是執行了一個函數而後計算出來的,這種特性的使用方式遵循了統一訪問的原則.app
在python中經過property方法能夠實現提供set和get方法(接口)去設置和獲取全部的私有數據。ide
class Foo: def __init__(self,val): self.__NAME=val #將全部的數據屬性都隱藏起來 @property def name(self): return self.__NAME #obj.name訪問的是self.__NAME(這也是真實值的存放位置) @name.setter def name(self,value): if not isinstance(value,str): #在設定值以前進行類型檢查 raise TypeError('%s must be str' %value) self.__NAME=value #經過類型檢查後,將值value存放到真實的位置self.__NAME @name.deleter def name(self): raise TypeError('Can not delete') f=Foo('egon') print(f.name) # f.name=10 #拋出異常'TypeError: 10 must be str' del f.name #拋出異常'TypeError: Can not delete'
一個靜態屬性property本質就是實現了get,set,delete三種方法。函數
class Goods: def __init__(self): # 原價 self.original_price = 100 # 折扣 self.discount = 0.8 @property def price(self): #不能穿參數 # 實際價格 = 原價 * 折扣 new_price = self.original_price * self.discount return new_price @price.setter def price(self, value): #能傳一個參數 self.original_price = value @price.deleter def price(self): #不能傳參數 del self.original_price obj = Goods() obj.price # 獲取商品價格 obj.price = 200 # 修改商品原價 print(obj.price) del obj.price # 刪除商品原價
注意:set和get 方法使用的前提必需要有property屬性;spa
set能夠傳一個值,get和property不能傳值;code
把一個方法,變成一個類中的方法,這個方法就能夠直接被類調用,不須要依託任何對象。對象
當這個方法的操做只涉及靜態屬性的時候 就應該使用classmethod來裝飾這個方法.blog
class Goods: __discount = 0.8 def __init__(self,name,price): self.name = name self.__price = price @property def price(self): return self.__price * Goods.__discount @classmethod # 把一個方法 變成一個類中的方法,這個方法就直接能夠被類調用,不須要依託任何對象 def change_discount(cls,new_discount): # 修改折扣 cls.__discount = new_discount apple = Goods('蘋果',5) print(apple.price) Goods.change_discount(0.5) # Goods.change_discount(Goods) print(apple.price)
在徹底面向對象的程序中,若是一個函數 既和對象沒有關係 也和類沒有關係 那麼就用staticmethod將這個函數變成一個靜態方法.接口
class Login: def __init__(self,name,password): self.name = name self.pwd = password def login(self):pass @staticmethod def get_usr_pwd(): # 靜態方法 usr = input('用戶名 :') pwd = input('密碼 :') Login(usr,pwd) Login.get_usr_pwd()
補充:get
一、類方法和靜態方法,都是類調用的。
二、對象能夠調用類方法和靜態方法嗎?
能夠,通常狀況下,推薦用類名調用。
三、類方法,有一個默認參數,cls表明這個類。
四、靜態方法,沒有默認的參數,就像函數同樣。