私有屬性包括私有變量和私有方法,在 Python 中,在變量名或者方法名前面加上雙下劃線,這個(gè)屬性就成為了類的私有屬性。
?
為扶余等地區(qū)用戶提供了全套網(wǎng)頁(yè)設(shè)計(jì)制作服務(wù),及扶余網(wǎng)站建設(shè)行業(yè)解決方案。主營(yíng)業(yè)務(wù)為網(wǎng)站設(shè)計(jì)、成都網(wǎng)站設(shè)計(jì)、扶余網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠(chéng)的服務(wù)。我們深信只要達(dá)到每一位用戶的要求,就會(huì)得到認(rèn)可,從而選擇與我們長(zhǎng)期合作。這樣,我們也可以走得更遠(yuǎn)!
class Person:
def __init__(self, name, age):
self.__name = name
self.__age = age
def __fun(self):
print(self.__class__)
def say(self):
self.__fun() # 自動(dòng)轉(zhuǎn)換為 調(diào)用 _Person__fun 方法
print(self.__name + ' ' + str(self.__age)) # 自動(dòng)轉(zhuǎn)換為 調(diào)用 \_Person\_\_name 和 \_Person\_\_age 屬性~
p = Person('Kitty', 18)
p.say()
# 輸出結(jié)果:
Kitty 18上述示例中,__name 和 __age 為類的私有變量,私有變量?jī)H能在類中進(jìn)行訪問(wèn),在類的外部訪問(wèn)不到。
p = Person('Kitty', 18)
print(p.__name)
# 報(bào)錯(cuò)信息:
AttributeError: 'Person' object has no attribute '__name'?
其實(shí)在類中定義私有屬性時(shí),__name 和 __age 已經(jīng)自動(dòng)變形為 _Person__name 和 _Person__age,__fun 自動(dòng)變形為 _Person__fun,即私有屬性會(huì)自動(dòng)變形為_(kāi)類名__屬性~
p = Person('Kitty', 18)
print(p.__dict__)
# 輸出結(jié)果:
{'_Person__name': 'Kitty', '_Person__age': 18}?
當(dāng)在類的內(nèi)部通過(guò)屬性名稱訪問(wèn)私有屬性時(shí),會(huì)自動(dòng)進(jìn)行轉(zhuǎn)換,例如 self.__name 轉(zhuǎn)換為 self._Person__name,在類的外部不會(huì)進(jìn)行這樣的自動(dòng)轉(zhuǎn)換~
?
類的私有屬性只是在語(yǔ)法上做了訪問(wèn)限制,但是并沒(méi)有真正限制從外部的訪問(wèn)。在外部不能通過(guò) 對(duì)象.__屬性 來(lái)進(jìn)行訪問(wèn),但是可以通過(guò)變形后的屬性名來(lái)進(jìn)行訪問(wèn)~
p = Person('Kitty', 18)
# print(p.__name) # 不能這樣訪問(wèn)
print(p._Person__name)
p._Person__fun()
# 結(jié)果輸出:
Kitty
<class '__main__.Person'>對(duì)私有屬性的訪問(wèn)限制只是一種規(guī)范,在開(kāi)發(fā)過(guò)程中一般不允許在外部通過(guò)這種方式訪問(wèn)私有屬性~
?
私有屬性的變形只在類的內(nèi)部生效,在定義后的賦值操作,不會(huì)變形~
p = Person('Kitty', 18)
p.__name = 'abc'
print(p.__dict__)
print(p.__name) # 調(diào)用的是 __name 屬性,不是私有屬性
# 輸出結(jié)果:
{'_Person__name': 'Kitty', '_Person__age': 18, '__name': 'abc'} # 這個(gè)屬性就叫 __name
abc?
在子類中定義的私有屬性若是和父類中的私有屬性同名,不會(huì)覆蓋父類的這些私有屬性,因?yàn)檫@些私有屬性變形后的名稱不同,子類:_子類名__屬性,父類:_父類名__屬性~
class Fu:
__key = 123 # 靜態(tài)私有屬性
def __init__(self, name):
self.__name = name
class Zi(Fu):
def get_name(self):
print(self.__name) # 變形為 self._Zi__name
def get_key(self):
print(Fu.__key) # 變形為 self._Zi__key
zi = Zi('hello')
zi.get_name() # 報(bào)錯(cuò)信息:AttributeError: 'Zi' object has no attribute '_Zi__name'
zi.get_key() # 報(bào)錯(cuò)信息:AttributeError: type object 'Fu' has no attribute '_Zi__key'?
若是父類中定義的方法不想被子類調(diào)用到,可以將方法定義為私有方法~
class A:
def __fun(self): # 在定義時(shí)就變形為_(kāi)A__fun
print('from A')
def test(self):
self.__fun() # 變形為 self._A__fun(),即以當(dāng)前的類為準(zhǔn)
class B(A):
def __fun(self):
print('from B')
b=B()
b.test() # 調(diào)用 A類中的test方法,test方法中的 self.__fun() 調(diào)用的是 A類中的私有方法__fun()
# 輸出結(jié)果:
from A?
封裝的優(yōu)勢(shì)在于將類內(nèi)部的實(shí)現(xiàn)細(xì)節(jié)隱藏起來(lái),調(diào)用者無(wú)需了解,直接調(diào)用對(duì)應(yīng)的方法即可(方法名,參數(shù)都不改變),若功能需要改變,只需要在類的內(nèi)部進(jìn)行調(diào)整,外部的調(diào)用代碼無(wú)需改變~
property為內(nèi)置裝飾器函數(shù),只在面向?qū)ο笾惺褂谩property裝飾器 可以將 對(duì)方法的調(diào)用轉(zhuǎn)為 對(duì)變量的調(diào)用。示例如下:
class Person:
def __init__(self, name, age):
self.__name = name
self.__age = age
@property
def name(self):
return self.__name
@property
def age(self):
return self.__age
p = Person('Kitty', 18)
print(p.name)
print(p.age)
# 結(jié)果輸出:
Kitty
18p.name 和 p.age 其實(shí)是執(zhí)行了一個(gè)函數(shù),然后將結(jié)果返回。這種特性的使用方式遵循了統(tǒng)一訪問(wèn)的原則。
?
p.屬性 的這個(gè)過(guò)程也可以做一些運(yùn)算操作然后將結(jié)果返回~
class Room:
def __init__(self, width, length, high):
self.__width = width
self.__length = length
self.__high = high
def area(self):
return self.__width * self.__length * self.__high
room = Room(1, 2, 3)
print(room.area()) # 6除了 @property,還有 @屬性.setter和 @屬性.deleter,要注意的是,定義了 property 后才能定義 屬性.setter,屬性.deleter ~
class Person:
def __init__(self, name, age):
self.__name = name
self.__age = age
@property
def name(self):
return self.__name
@name.setter
def name(self, value):
if not isinstance(value, str): # 在設(shè)定值之前進(jìn)行類型檢查
raise TypeError('%s must be str' %value)
self.__name = value
@name.deleter
def name(self):
raise TypeError('Can not delete')
@property
def age(self):
return self.__age
p = Person('Kitty', 18)
p.name = 'nihao'
print(p.name)
del p.name # TypeError: Can not delete說(shuō)明:
執(zhí)行 p.name 的時(shí)候,調(diào)用 @name.setter 修飾的方法,這樣的賦值方式在真正的賦值之前可以做一些類型檢驗(yàn)的操作,或者別的自定義操作,更具靈活性~
執(zhí)行 del p.name 的時(shí)候,調(diào)用 @name.deleter 修飾的方法
?
在使用 @property,@屬性.setter 和 @屬性.deleter 的時(shí)候,這幾個(gè)地方必須保持一致,即屬性名稱需要保持一致。
上述示例也可以通過(guò)如下方式實(shí)現(xiàn):
class Person:
def __init__(self, name, age):
self.__name = name
self.__age = age
def get_name(self):
return self.__name
def set_name(self, value):
if not isinstance(value, str): # 在設(shè)定值之前進(jìn)行類型檢查
raise TypeError('%s must be str' %value)
self.__name = value
def del_name(self):
print('delete name')
name = property(get_name, set_name, del_name)
@property
def age(self):
return self.__ageTip:
.................^_^
分享題目:Python面向?qū)ο筇匦?封裝
標(biāo)題網(wǎng)址:http://chinadenli.net/article12/ppdpgc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站內(nèi)鏈、小程序開(kāi)發(fā)、關(guān)鍵詞優(yōu)化、域名注冊(cè)、外貿(mào)建站、品牌網(wǎng)站設(shè)計(jì)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)