在類中定義一個私有屬性以下:python
class Person(object): def __init__(self, name): self.__name = name # 定義私有屬性 self.__name p = Person('hkey') print(p.__name) # 外部不能直接調用私有屬性 執行結果: Traceback (most recent call last): File "E:/learn_python/day26/test6.py", line 11, in <module> print(p.__name) AttributeError: 'Person' object has no attribute '__name'
私有屬性的使用場景:編程
雖然私有屬性不能直接從外部調用,可是咱們能夠經過對象.__dict__ 嘗試來獲取這個屬性試試:app
class Person(object): def __init__(self, name): self.__name = name p = Person('hkey') print(p.__dict__) print(p._Person__name) 執行結果: {'_Person__name': 'hkey'} # 執行 p.__dict__ 會直接獲取對象的屬性和方法 hkey # 在外部能夠經過 p._Person__name 來獲取類中的私有屬性
使用對象經過 _類名__屬性名 來獲取屬性的方式並不推薦,在python中沒有強制不容許查看類中私有屬性,一切都靠自覺;函數
將類中的方法看成屬性查看修改刪除spa
一個實例: 寫一個類,計算圓的周長和麪積3d
from math import pi class Circle(object): def __init__(self, r): self.__r = r def per(self): # 圓的周長 return 2*pi*self.__r def area(self): # 圓的面積 return pi * self.__r **2 c = Circle(5) print(c.area()) print(c.per())
在上面的代碼中,咱們要計算圓的周長和麪積,都是經過對象.方法名() 去獲取的。當咱們使用 property 能夠經過 對象.屬性名 的方式調用函數內的方法,以下:code
from math import pi class Circle(object): def __init__(self, r): self.__r = r @property # 經過裝飾器的形式,將類中方法調用的方式修改成函數調用的方式 def per(self): return 2*pi*self.__r @property def area(self): return pi * self.__r **2 c = Circle(5) print(c.area) print(c.per)
屬性能夠從新賦值,可是當使用 property 轉換爲屬性調用的方式後,是不能直接賦值的。對象
class Person(object): def __init__(self, name): self.__name = name @property # 使用 property 改變類中函數的調用方式 def name(self): return self.__name + ' run.' p = Person('hkey') print(p.name)
當咱們要修改對象 p 的 name 屬性時,就須要使用 setterblog
class Person(object): def __init__(self, name): self.__name = name @property def name(self): return self.__name + ' run.' @name.setter # 使用 setter 裝飾器 def name(self, new_name): self.__name = new_name p = Person('hkey') print(p.name) p.name = 'xiaofei' # 就能夠實現重新賦值 print(p.name)
當使用 setter 時, 咱們要明確命名規則:繼承
當使用 setter 時,咱們不只能夠賦值,還能夠作一些判斷
class Person(object): def __init__(self, name): self.__name = name @property def name(self): return self.__name + ' run.' @name.setter def name(self, new_name): if new_name.isalpha(): # new_name 必須是有字母或漢字組成 self.__name = new_name p = Person('hkey') print(p.name) p.name = '123' # 字符串是由數字組成,賦值失敗 print(p.name)
這個組合中最不經常使用的裝飾器:
做用:當要刪除類中某個屬性的時候使用 deleter 具體使用以下
class Person(object): def __init__(self, name): self.__name = name @property def name(self): return self.__name + ' run.' @name.setter def name(self, new_name): if new_name.isalpha(): # new_name 必須是有字母或漢字組成 self.__name = new_name @name.deleter def name(self): print('\033[31;1m我要刪除類中【__name】屬性了.\033[0m') del self.__name p = Person('hkey') del p.name 執行結果: 我要刪除類中【__name】屬性了.
一個實例, 商品打折的例子。
class Goods(object): dicount = 0.5 def __init__(self, name, price): self.name = name self.__price = price @property def price(self): return self.__price * Goods.dicount apple = Goods('apple', 10) pear = Goods('pear', 5) print(apple.price) print(pear.price)
在上面的實例中,當要改變全部商品的折扣時,只須要修改 dicount, 全部商品的折扣都會改變了。
當要使用類方法時,須要知足如下兩點:
仍是上面商品打折的例子:
dicount 是一個類屬性,咱們就能夠經過定義一個類方法來修改這個屬性
class Goods(object): dicount = 0.5 def __init__(self, name, price): self.name = name self.__price = price @property def price(self): return self.__price * Goods.dicount @classmethod # 定義一個類方法 def modify_discount(cls, new_discount): # cls: 類名,普通形參 cls.dicount = new_discount apple = Goods('apple', 10) pear = Goods('pear', 5) Goods.modify_discount(0.2) # 打 0.2 折 # 調用方式 類名.類方法(普通形參) print(apple.price) print(pear.price) 執行結果: 2.0 1.0
在徹底面向對象的程序中,若是一個函數即和對象沒有關係,也和類沒有關係。那麼就用 staticmethod 將這個函數變成一個靜態方法
好比在純面向對象的編程中,編寫一個用戶登陸的類:
class Login(object): def __init__(self, user, pwd): self.user = user self.pwd = pwd def login(self): pass @staticmethod # 靜態方法雖然是在類中,和類是徹底無關的; def get_user_pwd(): user = input('輸入用戶名:') pwd = input('輸入密碼:') Login(user, pwd) Login.get_user_pwd() # 進行登陸
使用類方法和靜態方法要注意如下幾點: