基于python3 類的屬性、方法、封裝、繼承實(shí)例講解
Python 類
Python中的類提供了面向?qū)ο缶幊痰乃谢竟δ埽侯惖睦^承機(jī)制允許多個(gè)基類,派生類可以覆蓋基類中的任何方法,方法中可以調(diào)用基類中的同名方法。
對(duì)象可以包含任意數(shù)量和類型的數(shù)據(jù)。
python類與c++類相似,提供了類的封裝,繼承、多繼承,構(gòu)造函數(shù)、析構(gòu)函數(shù)。
在python3中,所有類最頂層父類都是object類,與java類似,如果定義類的時(shí)候沒有寫出父類,則object類就是其直接父類。
類定義
類定義語法格式如下:
class ClassName: <statement-1> . . . <statement-N>
類對(duì)象:創(chuàng)建一個(gè)類之后,可以通過類名訪問、改變其屬性、方法
實(shí)例對(duì)象:類實(shí)例化后,可以使用其屬性,可以動(dòng)態(tài)的為實(shí)例對(duì)象添加屬性(類似javascript)而不影響類對(duì)象。
類的屬性
可以使用點(diǎn)(.)來訪問對(duì)象的屬性
也可以使用以下函數(shù)的方式來訪問屬性:
getattr(obj, name[, default]) : 訪問對(duì)象的屬性
hasattr(obj,name) : 檢查是否存在一個(gè)屬性
setattr(obj,name,value) : 設(shè)置一個(gè)屬性。如果屬性不存在,會(huì)創(chuàng)建一個(gè)新屬性
delattr(obj, name) : 刪除屬性
Python內(nèi)置類屬性
__dict__ : 類的屬性(包含一個(gè)字典,由類的數(shù)據(jù)屬性組成)
__doc__ :類的文檔字符串
__name__: 類名
__module__: 類定義所在的模塊(類的全名是'__main__.className',如果類位于一個(gè)導(dǎo)入模塊mymod中,那么className.__module__ 等于 mymod)
__bases__ : 類的所有父類構(gòu)成元素(包含了以個(gè)由所有父類組成的元組)
class Person: "Person類" def __init__(self, name, age, gender): print('進(jìn)入Person的初始化') self.name = name self.age = age self.gender = gender print('離開Person的初始化') def getName(self): print(self.name) p = Person('ice', 18, '男') print(p.name) # ice print(p.age) # 18 print(p.gender) # 男 print(hasattr(p, 'weight')) # False # 為p添加weight屬性 p.weight = '70kg' print(hasattr(p, 'weight')) # True print(getattr(p, 'name')) # ice print(p.__dict__) # {'age': 18, 'gender': '男', 'name': 'ice'} print(Person.__name__) # Person print(Person.__doc__) # Person類 print(Person.__dict__) # {'__doc__': 'Person類', '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__init__': <function Person.__init__ at 0x000000000284E950>, 'getName': <function Person.getName at 0x000000000284EA60>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__module__': '__main__'} print(Person.__mro__) # (<class '__main__.Person'>, <class 'object'>) print(Person.__bases__) # (<class 'object'>,) print(Person.__module__) # __main__
類的方法
在類地內(nèi)部,使用def關(guān)鍵字可以為類定義一個(gè)方法,與一般函數(shù)定義不同,類方法必須包含參數(shù)self,且為第一個(gè)參數(shù)。
類的專有方法:
__init__ 構(gòu)造函數(shù),在生成對(duì)象時(shí)調(diào)用
__del__ 析構(gòu)函數(shù),釋放對(duì)象時(shí)使用
__repr__ 打印,轉(zhuǎn)換
__setitem__按照索引賦值
__getitem__按照索引獲取值
__len__獲得長(zhǎng)度
__cmp__比較運(yùn)算
__call__函數(shù)調(diào)用
__add__加運(yùn)算
__sub__減運(yùn)算
__mul__乘運(yùn)算
__div__除運(yùn)算
__mod__求余運(yùn)算
__pow__稱方
__init__()方法是一種特殊的方法,被稱為類的構(gòu)造函數(shù)或初始化方法,當(dāng)創(chuàng)建了這個(gè)類的實(shí)例時(shí)就會(huì)調(diào)用該方法,與c++中構(gòu)造函數(shù)類似。只需在自定義的類中重寫__init__()方法即可。
class Person: def __init__(self, name, age, gender): print('進(jìn)入Person的初始化') self.name = name self.age = age self.gender = gender print('離開Person的初始化') def getName(self): print(self.name) # Person實(shí)例對(duì)象 p = Person('ice', 18, '男') print(p.name) print(p.age) print(p.gender) p.getName() # 進(jìn)入Person的初始化 # 離開Person的初始化 # ice # 18 # 男 # ice
析構(gòu)函數(shù) __del__ ,__del__在對(duì)象消逝的時(shí)候被調(diào)用,當(dāng)對(duì)象不再被使用時(shí),__del__方法運(yùn)行:
方法
實(shí)例方法:只能通過實(shí)例調(diào)用,實(shí)例方法第一個(gè)定義的參數(shù)只能是實(shí)例本身引用
class Myclass: def foo(self): print(id(self),'foo') a=Myclass()#既然是實(shí)例對(duì)象,那就要?jiǎng)?chuàng)建實(shí)例 a.foo()#輸出類里的函數(shù)地址 print(id(a))#輸出類對(duì)象的地址 #結(jié)果地址一樣
類方法:定義類方法,要使用裝飾器@classmethod,定義的第一個(gè)參數(shù)是能是類對(duì)象的引用,可以通過類或者實(shí)例直用
class Myclass: @classmethod#類裝飾器 def foo2(cls): print(id(cls),'foo2') #類對(duì)象,直接可以調(diào)用,不需要實(shí)例化 print(id(Myclass),'yy') Myclass.foo2()#直接可以調(diào)用
靜態(tài)方法:定義靜態(tài)方法使用裝飾器@staticmethod,沒有默認(rèn)的必須參數(shù),通過類和實(shí)例直接調(diào)用
class Myclass: @staticmethod#靜態(tài)方法 def foo3(): print('foo3') Myclass.foo3()#沒有參數(shù) a.foo3() #結(jié)果foo3
類的封裝
python通過變量名命名來區(qū)分屬性和方法的訪問權(quán)限,默認(rèn)權(quán)限相當(dāng)于c++和java中的public
類的私有屬性: __private_attrs:兩個(gè)下劃線開頭,聲明該屬性為私有,不能在類地外部被使用或直接訪問。在類內(nèi)部的方法中使用時(shí)self.__private_attrs。
類的私有方法:__private_method:兩個(gè)下劃線開頭,聲明該方法為私有方法,不能在類地外部調(diào)用。在類的內(nèi)部調(diào)用 self.__private_methods
雖然python不允許實(shí)例化的類訪問私有數(shù)據(jù),但可以使用 object._className__attrName 訪問屬性。其實(shí)python內(nèi)部私有化的實(shí)現(xiàn)只是將attrName屬性變?yōu)榱薩className__attrName而已
class Demo: __id = 123456 def getId(self): return self.__id temp = Demo() # print(temp.__id) # 報(bào)錯(cuò) AttributeError: 'Demo' object has no attribute '__id' print(temp.getId()) # 123456 print(temp._Demo__id) # 123456
類的繼承
面向?qū)ο蟮木幊處淼闹饕锰幹皇谴a的重用,實(shí)現(xiàn)這種重用的方法之一是通過繼承機(jī)制。繼承完全可以理解成類之間的類型和子類型關(guān)系。
需要注意的地方:繼承語法 class 派生類名(基類名)://... 基類名寫作括號(hào)里,基本類是在類定義的時(shí)候,在元組之中指明的。
在python中繼承中的一些特點(diǎn):
1:在繼承中基類的構(gòu)造(__init__()方法)不會(huì)被自動(dòng)調(diào)用,它需要在其派生類的構(gòu)造中親自專門調(diào)用。使用super().__init__()或parentClassName.__init__()
2:在調(diào)用基類的方法時(shí),需要加上基類的類名前綴,且需要帶上self參數(shù)變量。區(qū)別于在類中調(diào)用普通函數(shù)時(shí)并不需要帶上self參數(shù)
3:Python總是首先查找對(duì)應(yīng)類型的方法,如果它不能在派生類中找到對(duì)應(yīng)的方法,它才開始到基類中逐個(gè)查找。(先在本類中查找調(diào)用的方法,找不到才去基類中找)。
如果在繼承元組中列了一個(gè)以上的類,那么它就被稱作"多重繼承" 。
語法:
派生類的聲明,與他們的父類類似,繼承的基類列表跟在類名之后。
多態(tài)
如果父類方法的功能不能滿足需求,可以在子類重寫父類的方法。實(shí)例對(duì)象調(diào)用方法時(shí)會(huì)調(diào)用其對(duì)應(yīng)子類的重寫后的方法
python3.3 類與繼承 小例
hon中的類提供了面向?qū)ο缶幊痰乃谢竟δ埽侯惖睦^承機(jī)制允許多個(gè)基類,派生類可以覆蓋基類中的任何方法,方法中可以調(diào)用基類中的同名方法。
class Base: def __init__(self): self.data=[] def add(self,x): self.data.append(x) def addtwice(self,x): self.add(x) self.add(x) # child extends base class Child(Base): def plus(self,a,b): return a+b oChild=Child() oChild.add("str1") oChild.add(999) oChild.addtwice(4) print(oChild.data) print(oChild.plus(2,3))
對(duì)象可以包含任意數(shù)量和類型的數(shù)據(jù)。
python類與c++類相似,提供了類的封裝,繼承、多繼承,構(gòu)造函數(shù)、析構(gòu)函數(shù)。
在python3中,所有類最頂層父類都是object類,與java類似,如果定義類的時(shí)候沒有寫出父類,則object類就是其直接父類。
類定義
類定義語法格式如下:
class ClassName: <statement-1> . . . <statement-N>
類對(duì)象:創(chuàng)建一個(gè)類之后,可以通過類名訪問、改變其屬性、方法
實(shí)例對(duì)象:類實(shí)例化后,可以使用其屬性,可以動(dòng)態(tài)的為實(shí)例對(duì)象添加屬性(類似javascript)而不影響類對(duì)象。
類的屬性
可以使用點(diǎn)(.)來訪問對(duì)象的屬性
也可以使用以下函數(shù)的方式來訪問屬性:
getattr(obj, name[, default]) : 訪問對(duì)象的屬性
hasattr(obj,name) : 檢查是否存在一個(gè)屬性
setattr(obj,name,value) : 設(shè)置一個(gè)屬性。如果屬性不存在,會(huì)創(chuàng)建一個(gè)新屬性
delattr(obj, name) : 刪除屬性
Python內(nèi)置類屬性
__dict__ : 類的屬性(包含一個(gè)字典,由類的數(shù)據(jù)屬性組成)
__doc__ :類的文檔字符串
__name__: 類名
__module__: 類定義所在的模塊(類的全名是'__main__.className',如果類位于一個(gè)導(dǎo)入模塊mymod中,那么className.__module__ 等于 mymod)
__bases__ : 類的所有父類構(gòu)成元素(包含了以個(gè)由所有父類組成的元組)
class Person: "Person類" def __init__(self, name, age, gender): print('進(jìn)入Person的初始化') self.name = name self.age = age self.gender = gender print('離開Person的初始化') def getName(self): print(self.name) p = Person('ice', 18, '男') print(p.name) # ice print(p.age) # 18 print(p.gender) # 男 print(hasattr(p, 'weight')) # False # 為p添加weight屬性 p.weight = '70kg' print(hasattr(p, 'weight')) # True print(getattr(p, 'name')) # ice print(p.__dict__) # {'age': 18, 'gender': '男', 'name': 'ice'} print(Person.__name__) # Person print(Person.__doc__) # Person類 print(Person.__dict__) # {'__doc__': 'Person類', '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__init__': <function Person.__init__ at 0x000000000284E950>, 'getName': <function Person.getName at 0x000000000284EA60>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__module__': '__main__'} print(Person.__mro__) # (<class '__main__.Person'>, <class 'object'>) print(Person.__bases__) # (<class 'object'>,) print(Person.__module__) # __main__
類的方法
在類地內(nèi)部,使用def關(guān)鍵字可以為類定義一個(gè)方法,與一般函數(shù)定義不同,類方法必須包含參數(shù)self,且為第一個(gè)參數(shù)。
類的專有方法:
__init__ 構(gòu)造函數(shù),在生成對(duì)象時(shí)調(diào)用
__del__ 析構(gòu)函數(shù),釋放對(duì)象時(shí)使用
__repr__ 打印,轉(zhuǎn)換
__setitem__按照索引賦值
__getitem__按照索引獲取值
__len__獲得長(zhǎng)度
__cmp__比較運(yùn)算
__call__函數(shù)調(diào)用
__add__加運(yùn)算
__sub__減運(yùn)算
__mul__乘運(yùn)算
__div__除運(yùn)算
__mod__求余運(yùn)算
__pow__稱方
__init__()方法是一種特殊的方法,被稱為類的構(gòu)造函數(shù)或初始化方法,當(dāng)創(chuàng)建了這個(gè)類的實(shí)例時(shí)就會(huì)調(diào)用該方法,與c++中構(gòu)造函數(shù)類似。只需在自定義的類中重寫__init__()方法即可。
class Person: def __init__(self, name, age, gender): print('進(jìn)入Person的初始化') self.name = name self.age = age self.gender = gender print('離開Person的初始化') def getName(self): print(self.name) # Person實(shí)例對(duì)象 p = Person('ice', 18, '男') print(p.name) print(p.age) print(p.gender) p.getName() # 進(jìn)入Person的初始化 # 離開Person的初始化 # ice # 18 # 男 # ice
析構(gòu)函數(shù) __del__ ,__del__在對(duì)象消逝的時(shí)候被調(diào)用,當(dāng)對(duì)象不再被使用時(shí),__del__方法運(yùn)行:
類的封裝
python通過變量名命名來區(qū)分屬性和方法的訪問權(quán)限,默認(rèn)權(quán)限相當(dāng)于c++和java中的public
類的私有屬性: __private_attrs:兩個(gè)下劃線開頭,聲明該屬性為私有,不能在類地外部被使用或直接訪問。在類內(nèi)部的方法中使用時(shí)self.__private_attrs。
類的私有方法:__private_method:兩個(gè)下劃線開頭,聲明該方法為私有方法,不能在類地外部調(diào)用。在類的內(nèi)部調(diào)用 self.__private_methods
雖然python不允許實(shí)例化的類訪問私有數(shù)據(jù),但可以使用 object._className__attrName 訪問屬性。其實(shí)python內(nèi)部私有化的實(shí)現(xiàn)只是將attrName屬性變?yōu)榱薩className__attrName而已
class Demo: __id = 123456 def getId(self): return self.__id temp = Demo() # print(temp.__id) # 報(bào)錯(cuò) AttributeError: 'Demo' object has no attribute '__id' print(temp.getId()) # 123456 print(temp._Demo__id) # 123456
類的繼承
面向?qū)ο蟮木幊處淼闹饕锰幹皇谴a的重用,實(shí)現(xiàn)這種重用的方法之一是通過繼承機(jī)制。繼承完全可以理解成類之間的類型和子類型關(guān)系。
需要注意的地方:繼承語法 class 派生類名(基類名)://... 基類名寫作括號(hào)里,基本類是在類定義的時(shí)候,在元組之中指明的。
在python中繼承中的一些特點(diǎn):
1:在繼承中基類的構(gòu)造(__init__()方法)不會(huì)被自動(dòng)調(diào)用,它需要在其派生類的構(gòu)造中親自專門調(diào)用。使用super().__init__()或parentClassName.__init__()
2:在調(diào)用基類的方法時(shí),需要加上基類的類名前綴,且需要帶上self參數(shù)變量。區(qū)別于在類中調(diào)用普通函數(shù)時(shí)并不需要帶上self參數(shù)
3:Python總是首先查找對(duì)應(yīng)類型的方法,如果它不能在派生類中找到對(duì)應(yīng)的方法,它才開始到基類中逐個(gè)查找。(先在本類中查找調(diào)用的方法,找不到才去基類中找)。
如果在繼承元組中列了一個(gè)以上的類,那么它就被稱作"多重繼承" 。
語法:
派生類的聲明,與他們的父類類似,繼承的基類列表跟在類名之后。
多態(tài)
如果父類方法的功能不能滿足需求,可以在子類重寫父類的方法。實(shí)例對(duì)象調(diào)用方法時(shí)會(huì)調(diào)用其對(duì)應(yīng)子類的重寫后的方法
python3.3 類與繼承 小例
class Base: def __init__(self): self.data=[] def add(self,x): self.data.append(x) def addtwice(self,x): self.add(x) self.add(x) # child extends base class Child(Base): def plus(self,a,b): return a+b oChild=Child() oChild.add("str1") oChild.add(999) oChild.addtwice(4) print(oChild.data) print(oChild.plus(2,3))
以上這篇基于python3 類的屬性、方法、封裝、繼承實(shí)例講解就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- 在Python中使用__slots__方法的詳細(xì)教程
- Python中的__SLOTS__屬性使用示例
- Python中的__slots__示例詳解
- 用Python中的__slots__緩存資源以節(jié)省內(nèi)存開銷的方法
- python中__slots__用法實(shí)例
- python中的__slots__使用示例
- Python中__slots__屬性介紹與基本使用方法
- python使用__slots__讓你的代碼更加節(jié)省內(nèi)存
- Python類中的魔法方法之 __slots__原理解析
- 實(shí)例講解Python中的私有屬性
- Python編程之屬性和方法實(shí)例詳解
- python3中使用__slots__限定實(shí)例屬性操作分析
相關(guān)文章
Python第三方庫face_recognition在windows上的安裝過程
今天為大家介紹下face recognition在Windows系統(tǒng)上安裝與使用,但在Windows平臺(tái)上face recognition性能會(huì)有所下降2019-05-05詳解python中init方法和隨機(jī)數(shù)方法
這篇文章主要介紹了python中init方法和隨機(jī)數(shù)方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-03-03python自動(dòng)化測(cè)試三部曲之request+django實(shí)現(xiàn)接口測(cè)試
這篇文章主要介紹了python自動(dòng)化測(cè)試三部曲之request+django實(shí)現(xiàn)接口測(cè)試,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10使用Python的Twisted框架構(gòu)建非阻塞下載程序的實(shí)例教程
Twisted的異步工作模式使其在非阻塞情況下可以擁有較高的性能,這里我們來看一下使用Python的Twisted框架構(gòu)建非阻塞下載程序的實(shí)例教程,包括服務(wù)器端與客戶端的實(shí)踐.2016-05-05Python機(jī)器學(xué)習(xí)之基于Pytorch實(shí)現(xiàn)貓狗分類
看了許多關(guān)于PyTorch的入門文章,大抵是從torchvision.datasets中自帶的數(shù)據(jù)集進(jìn)行訓(xùn)練,導(dǎo)致很難把PyTorch運(yùn)用于自己的數(shù)據(jù)集上,真正地靈活運(yùn)用PyTorch,本文詳細(xì)介紹了怎么利用Pytorch實(shí)現(xiàn)貓狗分類,需要的朋友可以參考下2021-06-06Python TensorFlow 2.6獲取MNIST數(shù)據(jù)的示例代碼
這篇文章主要介紹了Python TensorFlow 2.6獲取MNIST數(shù)據(jù)的的相關(guān)示例,文中有詳細(xì)的代碼示例供大家參考,對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-04-04實(shí)例解析Python設(shè)計(jì)模式編程之橋接模式的運(yùn)用
這篇文章主要介紹了Python設(shè)計(jì)模式編程之橋接模式的運(yùn)用,橋接模式主張把抽象部分與它的實(shí)現(xiàn)部分分離,需要的朋友可以參考下2016-03-03python smtplib模塊自動(dòng)收發(fā)郵件功能(二)
這篇文章主要為大家詳細(xì)介紹了python smtplib模塊自動(dòng)收發(fā)郵件功能的第二篇,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-05-05Python實(shí)現(xiàn)SMTP郵件發(fā)送
這篇文章主要介紹了基于python實(shí)現(xiàn)SMTP發(fā)送郵件教程,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-06-06