欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python面向?qū)ο笾械姆庋b詳情

 更新時(shí)間:2022年03月07日 11:33:57   作者:搬磚,贊路費(fèi)  
這篇文章主要介紹了Python面向?qū)ο笾械姆庋b詳情,在python中也有對(duì)對(duì)象的封裝操作,使其對(duì)外只提供固定的訪問模式,不能訪問其內(nèi)部的私有屬性和私有方法。下文詳細(xì)內(nèi)容,需要的小伙伴可以參考一下

一 封裝的概念

封裝其實(shí)在我們的生活中處處都是,如電視機(jī),電腦,手機(jī)等物品。我們通常只能看到其外部的形狀,以及使用他們提供的功能,并不能看到其內(nèi)部復(fù)雜的硬件組成,這些都是封裝好的,不能讓我們看到,避免我們的一些“特殊”操作,使其不能正常工作。編程源于生活。在python中也有對(duì)對(duì)象的封裝操作,使其對(duì)外只提供固定的訪問模式,不能訪問其內(nèi)部的私有屬性和私有方法。python中的封裝,一般指的是對(duì)類屬性,類方法的封裝,即類屬性私有化和類方法私有化,具體如下面的小結(jié)所講。

二 _ 和__ 對(duì)屬性和方法的私有化

1. 單下劃線_

當(dāng)類中的屬性和方法以_ 單下劃線開頭時(shí),即說明這是類的保護(hù)變量和保護(hù)方法,按照編碼約定,是不希望被外部訪問的。但如果你要進(jìn)行訪問,也不會(huì)報(bào)錯(cuò)。

如下:

class A():
? ? #_ 聲明是保護(hù)屬性和保護(hù)方法
? ? _name = '張三'
? ? def __init__(self):
? ? ? ? self._age = 23

? ? def _method(self):
? ? ? ? print("我叫{},今年{}歲".format(self._name, self._age))

if __name__ == '__main__':
? ? a = A()
? ? #打印類A的dir
? ? print(a.__dir__())
? ? #訪問保護(hù)變量和保護(hù)方法
? ? print(a._name)
? ? a._method()

輸出結(jié)果:

>>>
['_age', '__module__', '_name', '__init__', '_method', '__dict__', '__weakref__', '__doc__', '__repr__', '__hash__', '__str__', '__getattribute__', '__setattr__', '__delattr__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__new__', '__reduce_ex__', '__reduce__', '__subclasshook__', '__init_subclass__', '__format__', '__sizeof__', '__dir__', '__class__']
張三
我叫張三,今年23歲

可以看出,以_單下劃線開頭的屬性和方法其實(shí)在類外部是可以訪問的,但是根據(jù)約定,當(dāng)我們看見這樣的屬性和方法時(shí),不應(yīng)該在外部對(duì)其進(jìn)行訪問。

2. 雙下劃線__

上面以單下劃線開頭的屬性和方法雖然是保護(hù)的,但是在外部還是可以訪問的。而當(dāng)你看到以雙下劃線__開頭的屬性和方法時(shí),請(qǐng)記住它們是類的私有屬性和私有方法,在類外以及子類中以常規(guī)訪問類屬性類方法的方法是無法訪問的,也無法對(duì)其進(jìn)行修改,如下

class B():
? ? #__ 聲明是私有化的
? ? __name = '張三'

? ? def __init__(self):
? ? ? ? self.__age = 23
? ? ? ? self.__luange = 'python'

? ? def __method(self):
? ? ? ? #私有方法
? ? ? ? print("我叫{},今年{}歲,我喜歡{}。".format(self.__name, self.__age, self.__luange))

? ? def fun(self):
? ? ? ? #公有方法
? ? ? ? print("this is a public method")
?
?if __name__ == '__main__':
? ? b = B()
? ? #打印類B的dir
? ? print(b.__dir__())
? ? #訪問類B的私有屬性和私有方法
? ? b.fun()
? ? print(b.__name, b.__age, b.__luange)
? ? b.__method()

輸出結(jié)果:

>>>
['_B__age', '_B__luange', '__module__', '_B__name', '__init__', '_B__method', 'fun', '__dict__', '__weakref__', '__doc__', '__repr__', '__hash__', '__str__', '__getattribute__', '__setattr__', '__delattr__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__new__', '__reduce_ex__', '__reduce__', '__subclasshook__', '__init_subclass__', '__format__', '__sizeof__', '__dir__', '__class__']
this is a public method
Traceback (most recent call last):
  File "C:/Users/admin/python-learning/python學(xué)習(xí)文件/python基礎(chǔ)/python類封裝.py", line 56, in <module>
    print(b.__name, b.__age, b.__luange)
AttributeError: 'B' object has no attribute '__name'

從結(jié)果可以看出,訪問類B的公有方法fun()是正常輸出的,但是當(dāng)我們?cè)L問私有屬性name時(shí)就拋錯(cuò):類B沒有name屬性。上面單下劃線時(shí),我們打印類A的dir,可以看到類A的name屬性和method方法在dir里面是下面這樣的

上面我們也打印了類B的私有屬性和私有方法,如下:

可以看到私有屬性和私有方法都變成了_B__屬性和_B__方法的形式,所以我們?cè)谏厦嬉訽_ name或者name的形式去訪問是報(bào)錯(cuò)的,其實(shí)我們?nèi)绻?類名(). _ 類名__ 屬性(實(shí)例屬性)或者類名. _ 類名__ 屬性(類屬性)的形式去訪問,還是會(huì)訪問成功的。如下

class B():
? ? #__ 聲明是私有化的
? ? __name = '張三'

? ? def __init__(self):
? ? ? ? self.__age = 23
? ? ? ? self.__luange = 'python'

? ? def __method(self):
? ? ? ? #私有方法
? ? ? ? print("我叫{},今年{}歲,我喜歡{}。".format(self.__name, self.__age, self.__luange))

? ? def fun(self):
? ? ? ? #公有方法
? ? ? ? print("this is a public method")

if __name__ == '__main__':
? ? b = B()
? ? #打印類B的dir
? ? print(b.__dir__())
? ? #訪問類B的私有屬性和私有方法
? ? b.fun()
? ? print(B._B__name, b._B__age, b._B__luange)
? ? b._B__method()

結(jié)果如下:

>>>
['_B__age', '_B__luange', '__module__', '_B__name', '__init__', '_B__method', 'fun', '__dict__', '__weakref__', '__doc__', '__repr__', '__hash__', '__str__', '__getattribute__', '__setattr__', '__delattr__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__new__', '__reduce_ex__', '__reduce__', '__subclasshook__', '__init_subclass__', '__format__', '__sizeof__', '__dir__', '__class__']
this is a public method
張三 23 python
我叫張三,今年23歲,我喜歡python。

3. 子類中訪問父類的私有屬性和私有方法

子類無法訪問父類的私有屬性和私有方法:

class B():
? ? #__ 聲明是私有化的
? ? __name = '張三'

? ? def __init__(self):
? ? ? ? self.__age = 23
? ? ? ? self.__luange = 'python'

? ? def __method(self):
? ? ? ? #私有方法
? ? ? ? print("我叫{},今年{}歲,我喜歡{}。".format(self.__name, self.__age, self.__luange))

? ? def fun(self):
? ? ? ? #公有方法
? ? ? ? print("this is a public method")

class C(B):

? ? def __init__(self):
? ? ? ? super().__init__()

? ? def fun1(self):
? ? ? ? #訪問父類B的私有屬性和私有方法
? ? ? ? print(self.__name, self.__age, self.__luange)
? ? ? ? self.__method()

if __name__ == '__main__':
? ? c = C()
? ? c.fun1()

輸出結(jié)果:

>>>
AttributeError: 'C' object has no attribute '_C__name'
AttributeError: 'C' object has no attribute '_C__method'

可以看出子類也是無法訪問父類的私有屬性和私有方法的。

當(dāng)子類中的的屬性和方法與父類的私有屬性,私有方法同名時(shí),不會(huì)覆蓋父類的私有屬性和私有方法。

class B():
? ? #__ 聲明是私有化的
? ? __name = '張三'

? ? def __init__(self):
? ? ? ? self.__age = 23
? ? ? ? self.__luange = 'python'

? ? def __method(self):
? ? ? ? #私有方法
? ? ? ? print("我叫{},今年{}歲,我喜歡{}。".format(self.__name, self.__age, self.__luange))

? ? def fun(self):
? ? ? ? #公有方法
? ? ? ? print("this is a public method")

class C(B):
? ? __name = '李四'
? ? def __init__(self):
? ? ? ? super().__init__()
? ? ? ? self.__age = 24
? ? ? ? self.__luange = 'C++'

? ? def fun1(self):
? ? ? ? #訪問父類B的私有屬性和私有方法
? ? ? ? print(self.__name, self.__age, self.__luange)
? ? ? ? self.__method()

? ? def __method(self):
? ? ? ? #類C的私有方法,與父類方法同名,但不重寫父類方法
? ? ? ? print("我叫{},今年{}歲,我喜歡{}。".format(self.__name, self.__age, self.__luange))
? ? ? ? #調(diào)用父類的私有方法
? ? ? ? B()._B__method()

if __name__ == '__main__':
? ? c = C()
? ? #訪問類C的私有方法
? ? c._C__method()

結(jié)果如下:

>>>
我叫李四,今年24歲,我喜歡C++。
我叫張三,今年23歲,我喜歡python。

可以看到,子類C并沒有重寫父類B的__method()方法。這是為什么呢?我們打印一下B和C的dir,如下:

>>>
['_B__age', '_B__luange', '_C__age', '_C__luange', 'fun1',
 '_C__method', '__doc__', '_B__name', '_B__method', '_C__name', ...]

可以看到,在類C的dir中,父類B的私有屬性和私有方法是以 _B__屬性(方法)存在的,二類C自己的私有屬性和私有方法是以_C__屬性(方法)存在的,即類的私有屬性和私有方法會(huì)以_類名_屬性(方法)的形式存在dir中,所以當(dāng)子類的屬性和方法與父類的私有屬性和私有方法同名時(shí),并不會(huì)覆蓋重寫。

三 訪問及修改類的私有屬性和私有方法

類通過對(duì)屬性和方法的私有化,可以對(duì)其起到封裝保護(hù)作用。但是,當(dāng)外部需要訪問和改變時(shí)怎么辦呢?就像電視機(jī),電腦也會(huì)對(duì)外提供固定的接口。
上面,雖然我們可以通過類名(). _ 類名__ 屬性(實(shí)例屬性)或者類名. _ 類名__ 屬性(類屬性)的形式去訪問類的私有屬性和私有方法,但是這是違反編程規(guī)范的,不支持這么做,就像不會(huì)拆開電視機(jī)對(duì)其操作一樣。

正確對(duì)類的私有屬性和私有方法進(jìn)行訪問修改的一般有兩種發(fā)方法,如下:

1. 自定義公有方法

class D():
? ? __name = '張三'

? ? def __init__(self):
? ? ? ? self.__age = 23
? ? ? ? self.__luange = 'python'

? ? def __method(self):
? ? ? ? print("我叫{},今年{}歲,我喜歡{}。".format(self.__name, self.__age, self.__luange))

? ? def get_value(self):
? ? ? ? return self.__name, self.__age, self.__luange

? ? def get_method(self):
? ? ? ? self.__method()

? ? def set_value(self, name, age, luange):
? ? ? ? self.__name, self.__age, self.__luange = name, age, luange

if __name__ == '__main__':
? ? d = D()
? ? #通過get_value方法訪問私有屬性
? ? print(d.get_value())
? ? #通過get_method方法訪問私有方法
? ? print('=' * 30)
? ? d.get_method()
? ? #通過set_value方法修改私有屬性
? ? print('='*30)
? ? print(d.get_value())
? ? d.set_value('王二麻子', 25, 'Linux')
? ? print(d.get_value())
? ? d.get_method()

輸出結(jié)果:

>>>
('張三', 23, 'python')
==============================
我叫張三,今年23歲,我喜歡python。
==============================
('張三', 23, 'python')
('王二麻子', 25, 'Linux')
我叫王二麻子,今年25歲,我喜歡Linux。

可以看到,我們通過自定義的的get_value(),get_method()以及set_value()方法就實(shí)現(xiàn)了對(duì)私有屬性和私有方法的訪問和修改。

2. property

property一般有兩個(gè)作用,如下:

  • 作為裝飾器,@property 將類的方法轉(zhuǎn)為只讀的類屬性
  • property 重新實(shí)現(xiàn)一個(gè)屬性的 getter 和 setter 方法

來看看下面這個(gè)E類,如下:

class E():
? ? __name = '張三'

? ? def __init__(self):
? ? ? ? self.__age = 23
? ? ? ? self.__luange = 'python'

? ? def __method(self):
? ? ? ? print("我叫{},今年{}歲,我喜歡{}。".format(self.__name, self.__age, self.__luange))

? ? def get_value(self):
? ? ? ? return self.__name

? ? def set_value(self, name):
? ? ? ? self.__name = name

? ? getValue = property(get_value, set_value)

? ? @property
? ? def get_method(self):
? ? ? ? self.__method()

if __name__ == '__main__':
? ? e = E()
? ? #訪問
? ? print(e.getValue)
? ? e.get_method
? ? #修改
? ? e.getValue = '王二'
? ? print(e.getValue)

結(jié)果:

>>>
張三
我叫張三,今年23歲,我喜歡python。
王二

可以看到,我們將get_valueset_value方法傳入property后,類方法就轉(zhuǎn)換成類屬性,并賦值給getValue變量。此時(shí)e.getValue就是只讀,即get_value方法,e.value = ‘王二’ 就是修改,即get_value方法。同一,通過@propert,將get_method方法,變成了屬性。

下面property 重新實(shí)現(xiàn)一個(gè)屬性的 getter 和 setter 方法,不同于上面的寫法,較上面常用。

class E():
? ? __name = '張三'

? ? def __init__(self):
? ? ? ? self.__age = 23
? ? ? ? self.__luange = 'python'

? ? def __method(self):
? ? ? ? print("我叫{},今年{}歲,我喜歡{}。".format(self.__name, self.__age, self.__luange))

? ? @property
? ? def name(self):
? ? ? ? return self.__name
? ? @name.setter
? ? def name(self, name):
? ? ? ? self.__name = name

if __name__ == '__main__':
? ? e = E()
? ? #訪問
? ? print(e.name)
? ? #修改
? ? print("修改前:", e.name)
? ? e.name = '隔壁老王'
? ? print("修改后:", e.name)

輸出結(jié)果:

>>>
張三
修改前: 張三
修改后: 隔壁老王

上面是首先把name方法送給propert裝飾器進(jìn)行裝飾,然后調(diào)用裝飾后的setter方法,即可實(shí)現(xiàn)對(duì)私有屬性進(jìn)行修改。

到此這篇關(guān)于Python面向?qū)ο笾械姆庋b詳情的文章就介紹到這了,更多相關(guān)Python封裝內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • python?pandas如何使用loc和iloc讀取行數(shù)據(jù)或列數(shù)據(jù)

    python?pandas如何使用loc和iloc讀取行數(shù)據(jù)或列數(shù)據(jù)

    這篇文章主要給大家介紹了關(guān)于python?pandas如何使用loc和iloc讀取行數(shù)據(jù)或列數(shù)據(jù)的相關(guān)資料,在學(xué)習(xí)機(jī)器學(xué)習(xí)的過程中對(duì)數(shù)據(jù)進(jìn)行預(yù)處理時(shí)避免不了需要使用Pandas進(jìn)行大量操,需要的朋友可以參考下
    2023-10-10
  • keras 獲取某層的輸入/輸出 tensor 尺寸操作

    keras 獲取某層的輸入/輸出 tensor 尺寸操作

    這篇文章主要介紹了keras 獲取某層的輸入/輸出 tensor 尺寸操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-06-06
  • Python3 requests模塊如何模仿瀏覽器及代理

    Python3 requests模塊如何模仿瀏覽器及代理

    這篇文章主要介紹了Python3 requests模塊如何模仿瀏覽器及代理,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-06-06
  • python數(shù)組如何添加整行或整列

    python數(shù)組如何添加整行或整列

    這篇文章主要介紹了python數(shù)組如何添加整行或整列問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • python命令行參數(shù)用法實(shí)例分析

    python命令行參數(shù)用法實(shí)例分析

    這篇文章主要介紹了python命令行參數(shù)用法,結(jié)合實(shí)例形式分析了Python基于optparse模塊處理命令行參數(shù)相關(guān)使用技巧,需要的朋友可以參考下
    2019-06-06
  • python 通過 pybind11 使用Eigen加速代碼的步驟

    python 通過 pybind11 使用Eigen加速代碼的步驟

    這篇文章主要介紹了python 通過 pybind11 使用Eigen加速代碼的步驟,幫助大家更好的理解和使用python,感興趣的朋友可以了解下
    2020-12-12
  • 詳解python 拆包可迭代數(shù)據(jù)如tuple, list

    詳解python 拆包可迭代數(shù)據(jù)如tuple, list

    拆包是指將一個(gè)結(jié)構(gòu)中的數(shù)據(jù)拆分為多個(gè)單獨(dú)變量中。下面通過本文給大家介紹python 拆包可迭代數(shù)據(jù)如tuple, list的相關(guān)資料,需要的朋友參考下吧
    2017-12-12
  • 在自動(dòng)化中用python實(shí)現(xiàn)鍵盤操作的方法詳解

    在自動(dòng)化中用python實(shí)現(xiàn)鍵盤操作的方法詳解

    今天小編就為大家分享一篇在自動(dòng)化中用python實(shí)現(xiàn)鍵盤操作的方法詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2019-07-07
  • 盤點(diǎn)十個(gè)超級(jí)好用的高級(jí)Python腳本

    盤點(diǎn)十個(gè)超級(jí)好用的高級(jí)Python腳本

    這篇文章主要介紹了盤點(diǎn)十個(gè)超級(jí)好用的高級(jí)Python腳本,我們經(jīng)常會(huì)遇到一些大小問題,其中有很多的問題,都是可以使用一些簡單的Python代碼就能解決,需要的朋友可以參考下
    2023-04-04
  • python使用python-pptx刪除ppt某頁實(shí)例

    python使用python-pptx刪除ppt某頁實(shí)例

    今天小編就為大家分享一篇python使用python-pptx刪除ppt某頁實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-02-02

最新評(píng)論