13 面對(duì)對(duì)象二 - 秘密的盒子

目錄

? 1. 特殊方法
? 2. 封裝
? 3. property裝飾器

1. 特殊方法

我們希望在創(chuàng)建對(duì)象時(shí),必須設(shè)置一個(gè)屬性,如果不設(shè)置對(duì)象將無(wú)法創(chuàng)建。(e.g.在創(chuàng)建人物對(duì)象,必須添加name屬性&自動(dòng)調(diào)用)

? 在類中可以定義一些特殊方法也稱為魔術(shù)方法 ' _*2 '
特殊方法格式:

__xxx__() #__開(kāi)頭 __結(jié)尾

? 特殊方法不需要我們調(diào)用,特殊方法會(huì)在特定時(shí)候(實(shí)例對(duì)象創(chuàng)建后)自動(dòng)調(diào)用(函數(shù)需要調(diào)用,特殊方法不需要)

  • 例子:


    image.png
class Person:
    def __init__(self,name):
        # 通過(guò)self向新創(chuàng)建的對(duì)象中初始化屬性
        self.name = name
    def speak(self):

        print('大家好,我是%s'%self.name)
p2 = Person('鋼鐵俠')
print(p2.name) #鋼鐵俠
p1 = Person('綠巨人')
print(p1.name) #綠巨人

p1.speak()#大家好,我是綠巨人
類的基本結(jié)構(gòu)
class 類名([父類]):

    公共的屬性...
    
    # 對(duì)象的初始化方法
    def __init__(self,.....):
        
        代碼塊
    
    # 其他的方法
    def m1(self,....):
       
       代碼塊
       
    def m2(self,....):
       
       代碼塊
    .......

2. 封裝

? 出現(xiàn)封裝的原因:我們需要一種方式來(lái)增強(qiáng)數(shù)據(jù)的安全性
? 1. 屬性不能隨意修改
? 2. 屬性不能改為任意的值

封裝是面向?qū)ο蟮娜筇匦灾?/p>

? 封裝是指隱藏對(duì)象中一些不希望被外部所訪問(wèn)到的屬性或方法
? 我們也可以提供給一個(gè)getter()和setter()方法是外部可以訪問(wèn)到屬性
? getter() 獲取對(duì)象中指定的屬性
? setter() 用來(lái)設(shè)置對(duì)象指定的屬性

雙下劃線開(kāi)頭的屬性,是對(duì)象的隱藏屬性,隱藏屬性只能在類的內(nèi)部訪問(wèn),無(wú)法通過(guò)對(duì)象訪問(wèn)。

  • 實(shí)際上這種方式將名字修改為 類名_屬性名
  • 例如 __name ---> _Person__name
# 可以對(duì)對(duì)象的屬性使用__開(kāi)頭 形如 __xxx
# 雙下劃線開(kāi)頭的屬性,是對(duì)象的隱藏屬性,隱藏屬性只能在類的內(nèi)部訪問(wèn),無(wú)法通過(guò)對(duì)象訪問(wèn)
# 實(shí)際上這種方式將名字修改為 _類名__屬性名 例如 __name ---> _Person__name
# 一般你要告訴別人這個(gè)屬性時(shí)封裝的 以 _開(kāi)頭

# 一般情況下,使用_開(kāi)頭的屬性都是私有屬性,沒(méi)有特殊情況不要修改私有屬性
class Person:

    def __init__(self,name):

        self._name = name

    def get_name(self):

        return self._name

    def set_name(self,name):

        self._name = name

p = Person('葫蘆娃')

print(p._name)
# 葫蘆娃

使用封裝,確實(shí)增加了類的定義的復(fù)雜程度,但是它也確保了數(shù)據(jù)的安全
? 隱藏屬性名,使調(diào)用這無(wú)法隨意的修改對(duì)象中的屬性
? 增加了getter()和setter()方法,很好控制屬性是否是只讀的
? 使用setter()設(shè)置屬性,可以在呢及數(shù)據(jù)的驗(yàn)證
? 使用getter()方法獲取屬性,使用setter()方法設(shè)置屬性可以在讀取屬性和修改屬性的同時(shí)做一些其他的處理

? 這種方式實(shí)際上依然可以在外部訪問(wèn),所以這種方式我們一般不用。一般我們會(huì)將一些私有屬性以_開(kāi)頭
? 一般情況下,使用_開(kāi)頭的屬性都是私有屬性,沒(méi)有特殊情況下不要修改私有屬性

3. property裝飾器

? 我們可以使用@property裝飾器來(lái)創(chuàng)建只讀屬性,@property裝飾器會(huì)將方法轉(zhuǎn)換為相同名稱的只讀屬性(原來(lái)需要方式.屬性(),現(xiàn)在可以直接方式.屬性),可以與所定義的屬性配合使用,這樣可以防止屬性被修改

class Person:

    def __init__(self,name):

        self._name = name

    def name(self):
        print('getter方法執(zhí)行了')
        # 這是一個(gè)getter()方法
        return self._name
p = Person('葫蘆娃')
print(p.name)
#<bound method Person.name of <__main__.Person object at 0x000001AC0A70A438>>
#不加()就報(bào)錯(cuò)
print(p.name())#葫蘆娃

簡(jiǎn)單

class Person:

    def __init__(self,name):

        self._name = name
    # property裝飾器 用來(lái)將一個(gè)方法轉(zhuǎn)換為對(duì)象的屬性
    @property
    def name(self):
        print('getter方法執(zhí)行了')
        # 這是一個(gè)getter()方法
        return self._name
p = Person('葫蘆娃')
print(p.name) # 葫蘆娃
print(p.name())#TypeError: 'str' object is not callable

防修改


class Person:

    def __init__(self,name):

        self._name = name
    # property裝飾器 用來(lái)將一個(gè)方法轉(zhuǎn)換為對(duì)象的屬性
    @property
    def name(self):
        print('getter方法執(zhí)行了')
        # 這是一個(gè)getter()方法
        return self._name
p = Person('葫蘆娃')

p.name = 'gangteixia' # AttributeError: can't set attribute



?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容