成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

怎么理解Python中的面向?qū)ο缶幊?/h1>

本篇內(nèi)容主要講解“怎么理解Python中的面向?qū)ο缶幊獭?,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“怎么理解Python中的面向?qū)ο缶幊獭卑?

10年積累的網(wǎng)站建設(shè)、成都做網(wǎng)站經(jīng)驗(yàn),可以快速應(yīng)對客戶對網(wǎng)站的新想法和需求。提供各種問題對應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識你,你也不認(rèn)識我。但先做網(wǎng)站設(shè)計(jì)后付款的網(wǎng)站建設(shè)流程,更有舟山免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。

Python支持多種類型的編程范式,例如過程式編程、函數(shù)式編程、面向?qū)ο缶幊?,而且還可以融合多種類型的范式。

現(xiàn)如今面向?qū)ο缶幊痰氖褂梅浅V泛。面向?qū)ο缶幊痰幕驹厥菍ο?,其包含的?shù)據(jù)成員稱為屬性,函數(shù)(例程、過程)稱為方法。

對象是類的實(shí)例。換句話說,類主要定義對象的結(jié)構(gòu),然后我們以類為模板創(chuàng)建對象。類不但包含方法定義,而且還包含所有實(shí)例共享的數(shù)據(jù)。

Python中的面向?qū)ο缶幊踢€包含其他很多方面。希望本文能夠?yàn)槟銓W(xué)習(xí)Python及實(shí)現(xiàn)面向?qū)ο筇峁┮粋€(gè)良好的開端。

創(chuàng)建Python類

我們可以使用關(guān)鍵字class定義Python類,關(guān)鍵字后面緊跟類的名稱、分號和類的實(shí)現(xiàn):

>>> class MyClass:
... pass
...

按照慣例,Python類的命名采用首字母大寫(即PascalCase)。

現(xiàn)在讓我們創(chuàng)建這個(gè)新類的一個(gè)實(shí)例,名為MyClass:

>>> a = MyClass()
>>> a
<__main__.MyClass object at 0x7f32ef3deb70>

語句a = MyClass()創(chuàng)建了MyClass的一個(gè)實(shí)例,并將它的引用賦值給變量a。

我們可以通過Python內(nèi)置的函數(shù)type()或直接通過屬性.__class__來獲取類型(即對象的類)。在拿到類(類型)之后,我們就可以利用屬性.__ name__獲取類的名字:

>>> type(a)

<class '__main__.MyClass'>

>>> a.__class__

<class '__main__.MyClass'>

>>> a.__class__.__name__

'MyClass'

順便提一句,Python類也是對象。它們是type的實(shí)例:

>>> type(MyClass)
<class 'type'>

下面,我們來定義一個(gè)方法。

Python中每個(gè)實(shí)例方法的第一個(gè)參數(shù)必須對應(yīng)于該實(shí)例,即該對象本身。按照慣例,這個(gè)參數(shù)名為self。后面是其他參數(shù)(如果有需要的話)。在調(diào)用方法時(shí),我們無需明確提供與參數(shù)self相對應(yīng)的參數(shù)。

通常,我們需要定義的一個(gè)最重要的方法是.__init__()。在類的實(shí)例創(chuàng)建后就會(huì)調(diào)用這個(gè)方法。該方法負(fù)責(zé)初始化類成員。我們定義的.__init__()如下:

>>> class MyClass:
... def __init__(self, arg_1, arg_2, arg_3):
... print(f'an instance of {type(self).__name__} created')
... print(f'arg_1: {arg_1}, arg_2: {arg_2}, arg_3: {arg_3}')
...

下面,我們來創(chuàng)建一個(gè)MyClass實(shí)例,看看這個(gè)初始化方法的具體工作。我們的.__init__()方法需要三個(gè)參數(shù)(arg_1、arg_2和arg_3),記住我們不需要傳遞與self對應(yīng)的第一個(gè)參數(shù)。所以,在實(shí)例化對象時(shí),我們需要傳遞三個(gè)參數(shù):

>>> a = MyClass(2, 4, 8)

an instance of MyClass created

arg_1: 2, arg_2: 4, arg_3: 8

上述聲明產(chǎn)生的結(jié)果如下:

  • 創(chuàng)建一個(gè)MyClass類型的對象的實(shí)例。

  • 自動(dòng)調(diào)用該實(shí)例的方法.__init__()。

  • 我們傳遞給MyClass()方法的參數(shù):(2,4和8)會(huì)被傳遞給.__init__()。

  • .__init__()執(zhí)行我們的請求,并輸出結(jié)果。它利用type(self).__name__獲取類的名稱。

現(xiàn)在我們得到了一個(gè)類,它有一個(gè)方法.__init__(),以及這個(gè)類的一個(gè)實(shí)例。

數(shù)據(jù)屬性

下面我們來修改MyClass,增加一些數(shù)據(jù)屬性。

我們利用.__init__()初始化和定義了實(shí)例,我們還可以在這個(gè)方法或其他實(shí)例方法中,通過給某個(gè)數(shù)據(jù)屬性賦值的方式改變屬性值:

>>> class MyClass:

... def __init__(self, arg_1, arg_2, arg_3):

... self.x = arg_1

... self._y = arg_2

... self.__z = arg_3

...

現(xiàn)在MyClass有三個(gè)數(shù)據(jù)屬性:

  • .x可以獲取arg_1的值

  • ._y可以獲取arg_2的值

  • .__ z可以獲取arg_3的值

我們可以利用Python的解包機(jī)制,用更緊湊的形式編寫這段代碼:

>>> class MyClass:

... def __init__(self, arg_1, arg_2, arg_3):

... self.x, self._y, self.__z = arg_1, arg_2, arg_3

...

屬性名稱中的下劃線(_)是為了表明這些屬性是“私有”屬性:

  • 開頭沒有下劃線的屬性(比如.x)通常可供對象外部的調(diào)用和修改。

  • 開頭擁有一個(gè)下劃線的屬性(比如._y)通常也可以從對象外部調(diào)用和修改。然而,下劃線是一種慣用的標(biāo)志,即該類的創(chuàng)建者強(qiáng)烈建議不要使用該變量。應(yīng)該僅通過類的功能成員(比如方法和屬性)調(diào)用和修改該變量。

  • 開頭擁有雙下劃線的屬性(比如.__ z)將在名字修飾過程中被改名(在本例中它將被改名為._MyClass__z)。你也可以通過這個(gè)新名稱從對象外部調(diào)用和修改它們。但是,我強(qiáng)烈反對這種做法。應(yīng)該盡通過類的功能成員以其原始名稱進(jìn)行調(diào)用和修改。

Python對象的數(shù)據(jù)屬性通常存儲(chǔ)在名為.__ dict__的字典中,它也是對象的屬性之一。但是,你也可以將數(shù)據(jù)屬性存儲(chǔ)在其他地方。我們可以直接訪問__dict__,或利用Python的內(nèi)置函數(shù)vars()獲取.__ dict__:

>>> a = MyClass(2, 4, 8)
>>> vars(a)
{'x': 2, '_y': 4, '_MyClass__z': 8}
>>> a.__dict__
{'x': 2, '_y': 4, '_MyClass__z': 8}

名字修飾過程把鍵'__z'變成了'_MyClass__z'。

我們可以把.__ dict__當(dāng)成普通的Python字典使用。

獲取和修改與數(shù)據(jù)屬性關(guān)聯(lián)的值的常規(guī)方法如下:

>>> a.x
2
>>> a._y
4
>>> a.__z
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
AttributeError: 'MyClass' object has no attribute '__z'
>>> a.x = 16
>>> a.x
16
>>> vars(a)
{'x': 16, '_y': 4, '_MyClass__z': 8}

請注意,我們無法訪問.__ z,因?yàn)?__ dict__沒有鍵'__z'。

實(shí)例方法

下面,我們來創(chuàng)建兩個(gè)實(shí)例方法:

●.set_z():修改.__ z。

●.get_z():返回.__ z的值。

請記住,每個(gè)實(shí)例方法的第一個(gè)參數(shù)(按照約定名為self)引用對象本身,但我們無需在調(diào)用方法時(shí)指定這個(gè)參數(shù):

>>> class MyClass:

... def __init__(self, arg_1, arg_2, arg_3):

... self.x, self._y, self.__z = arg_1, arg_2, arg_3

...

... def set_z(self, value):

... self.__z = value

...

... def get_z(self):

... return self.__z

...

>>> b = MyClass(2, 4, 8)

方法.get_z()和.set_z()提供了傳統(tǒng)的檢索和修改.__ z值的方法:

>>> b.get_z()
8
>>> b.set_z(16)
>>> vars(b)
{'x': 2, '_y': 4, '_MyClass__z': 16}

你也可以在.get_z()和.set_z()中添加其他功能,例如檢查數(shù)據(jù)的有效性。這種方法實(shí)現(xiàn)了面向?qū)ο缶幊讨械囊粋€(gè)主要概念:封裝。

屬性

還有一種方法(一種更Python的方式)訪問和修改數(shù)據(jù)屬性是使用屬性。屬性封裝了一系列方法:getter、setter和deleter,但其行為與普通的數(shù)據(jù)屬性相同。

下面的代碼實(shí)現(xiàn)了屬性.z,其中還包含.get_z()和.set_z()的功能:

>>> class MyClass:

... def __init__(self, arg_1, arg_2, arg_3):

... self.x, self._y, self.__z = arg_1, arg_2, arg_3

...

... @property

... def z(self):

... return self.__z

...

... @z.setter

... def z(self, value):

... self.__z = value

...

>>> b = MyClass(2, 4, 8)

如下,我們利用相應(yīng)的屬性.z來訪問和修改數(shù)據(jù)屬性.__ z:

>>> b.z
8
>>> b.z = 16
>>> vars(b)
{'x': 2, '_y': 4, '_MyClass__z': 16}

這段代碼比上述示例更精簡優(yōu)雅。

類與靜態(tài)方法

除了實(shí)例方法和屬性之外,類還可以擁有類方法和靜態(tài)方法。

下面讓我們?yōu)镸yClass添加三個(gè)方法:

>>> class MyClass:

... def __init__(self, arg_1, arg_2, arg_3):

... self.x, self._y, self.__z = arg_1, arg_2, arg_3

...

... def f(self, arg):

... print('instance method f called')

... print(f'instance: {self}')

... print(f'instance attributes:

{vars(self)}')

... print(f'class: {type(self)}')

... print(f'arg: {arg}')

...

... @classmethod

... def g(cls, arg):

... print('class method g called')

... print(f'cls: {cls}')

... print(f'arg: {arg}')

...

... @staticmethod

... def h(arg):

... print('static method h called')

... print(f'arg: {arg}')

...

>>> c = MyClass(2, 4, 8)

方法.f()是一個(gè)實(shí)例方法。實(shí)例方法的第一個(gè)參數(shù)是對象本身的引用。這些方法可以利用self訪問對象,利用vars(self)或self.__dict__訪問對象的數(shù)據(jù)屬性,還可以利用type(self)或self.__class__訪問對象對應(yīng)的類,而且它們還可以擁有自己的參數(shù)。

方法.g()的開頭包含修飾器@classmethod,表明這是一個(gè)類方法。每個(gè)類方法的第一個(gè)參數(shù)都會(huì)指向類本身,按照約定該參數(shù)名為cls。與實(shí)例方法的情況一樣,我們不需要明確提供與cls對應(yīng)的參數(shù)。而類方法可以利用cls和自己的參數(shù)訪問類本身。

方法.h()的開頭包含修飾器@staticmethod,表明這是一個(gè)靜態(tài)方法。靜態(tài)方法只能訪問自己的參數(shù)。

Python中常見的調(diào)用實(shí)例方法的方法如下:

>>> c.f('my-argument')
instance method f called
instance: <__main__.MyClass object at 0x7f32ef3def98>
instance attributes:
{'x': 2, '_y': 4, '_MyClass__z': 8}
class: <class '__main__.MyClass'>
arg: my-argument

通常,我們應(yīng)該直接通過類(而不是實(shí)例)調(diào)用類方法和靜態(tài)方法:

>>> MyClass.g('my-argument')
class method g called
cls: <class '__main__.MyClass'>
arg: my-argument
>>> MyClass.h('my-argument')
static method h called
arg: my-argument

請記住,我們不需要傳遞類方法的第一個(gè)參數(shù):與cls相對應(yīng)的參數(shù)。

但是,我們可以像下面這樣調(diào)用類方法和靜態(tài)方法:

>>> c.g('my-argument')
class method g called
cls: <class '__main__.MyClass'>
arg: my-argument
>>> c.h('my-argument')
static method h called
arg: my-argument

當(dāng)我們調(diào)用c.g或c.h,但實(shí)例成員沒有這樣的名稱時(shí),Python會(huì)搜索類和靜態(tài)成員。

繼承

繼承是面向?qū)ο缶幊痰牧硪粋€(gè)重要特性。在這個(gè)概念中,類(稱為子類或派生類)會(huì)繼承其他類(稱為超類或基類)的數(shù)據(jù)和函數(shù)成員。

在Python中,所有類都會(huì)默認(rèn)繼承Python自帶的類對象。但是,我們可以根據(jù)需要定義合適的類繼承層次結(jié)構(gòu)。

例如,我們可以創(chuàng)建一個(gè)名為MyOtherClass的新類,該類繼承了MyClass:

>>> class MyOtherClass(MyClass):
... def __init__(self, u, v, w, x, y, z):
... super().__init__(x, y, z)
... self.__u, self.__v, self.__w = u, v, w
... 
... def f_(self, arg):
... print('instance method f_ called')
... print(f'instance: {self}')
... print(f'instance attributes:
{vars(self)}')
... print(f'class: {type(self)}')
... print(f'arg: {arg}')
...
>>> d = MyOtherClass(1, 2, 4, 8, 16, 32)

如上,MyOtherClass擁有MyClass的成員:.x、._y、.__z以及.f()。你可以通過語句super().__init__(x, y, z)初始化基類的數(shù)據(jù)成員x、._y和.__z,該語句會(huì)調(diào)用基類的.__init__()方法。

除此之外,MyOtherClass還有自己的成員:.__u、.__v、.__w和.f_()。

下面,我們通過vars()獲取數(shù)據(jù)成員:

>>> vars(d)
{'x': 8,
 '_y': 16,
 '_MyClass__z': 32,
 '_MyOtherClass__u': 1,
 '_MyOtherClass__v': 2,
 '_MyOtherClass__w': 4}

我們可以調(diào)用基類和派生類中的所有方法:

>>> d.f('some-argument')
instance method f called
instance: <__main__.MyOtherClass object at 0x7f32ef3e7048>
instance attributes:
{'x': 8,
 '_y': 16,
 '_MyClass__z': 32,
 '_MyOtherClass__u': 1,
 '_MyOtherClass__v': 2,
 '_MyOtherClass__w': 4}
class: <class '__main__.MyOtherClass'>
arg: some-argument
>>> d.f_('some-argument')
instance method f_ called
instance: <__main__.MyOtherClass object at 0x7f32ef3e7048>
instance attributes:
{'x': 8,
 '_y': 16,
 '_MyClass__z': 32,
 '_MyOtherClass__u': 1,
 '_MyOtherClass__v': 2,
 '_MyOtherClass__w': 4}
class: <class '__main__.MyOtherClass'>
arg: some-argument

但是,如果派生類包含的某個(gè)成員與基類同名,則優(yōu)先使用派生類的成員。

到此,相信大家對“怎么理解Python中的面向?qū)ο缶幊獭庇辛烁畹牧私?,不妨來?shí)際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

網(wǎng)頁名稱:怎么理解Python中的面向?qū)ο缶幊?/a>
標(biāo)題URL:
http://jinyejixie.com/article42/ijjehc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供App設(shè)計(jì)、網(wǎng)站策劃、企業(yè)建站企業(yè)網(wǎng)站制作、標(biāo)簽優(yōu)化網(wǎng)站內(nèi)鏈

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站建設(shè)
广昌县| 萨迦县| 固始县| 石林| 邻水| 察雅县| 邻水| 无为县| 梅河口市| 泸西县| 南康市| 临漳县| 石河子市| 永川市| 赣榆县| 达孜县| 赣州市| 忻城县| 桃园市| 龙海市| 鱼台县| 兰州市| 盘锦市| 祁门县| 淳安县| 潜山县| 五寨县| 枣强县| 巴里| 乌拉特中旗| 泽州县| 沈阳市| 曲周县| 凉城县| 灯塔市| 台北县| 龙川县| 南阳市| 宁阳县| 牙克石市| 报价|