Python面向对象---类的基本使用
1、面向對象
類(class):是一種用來描述具有相同屬性和方法的對象的集合。
類變量:類變量在整個實例化的對象中是公用的。一般定義在類中且在函數體之外。
方法:類中的函數
數據成員:類變量或者實例變量用于處理類及其實例對象的相關的數據。
方法重寫:如果從父類繼承的方法不能滿足子類的需求,可以對其進行改寫,這個過程叫方法的覆蓋(override),也稱為方法的重寫。
局部變量:定義在方法中的變量,只作用于當前實例的類。
實例變量:在類的聲明中,屬性是用變量來表示的,這種變量就稱為實例變量,實例變量就是一個用 self 修飾的變量。
繼承:即一個派生類(derived class)繼承基類(base class)的字段和方法。繼承也允許把一個派生類的對象作為一個基類對象對待。就像我們定義一個fruit(水果)類,然后又定義了一個fruit類的派生類apple(蘋果),它有著fruit類的一些屬性和方法,也有著自己的一些獨特的屬性和方法,和fruit類是一種’is-a’的關系。
實例化:類的一個具體對象,類像當于一個模板,只有我們將其實例化為一個對象后才能對其進行相應的操作。
對象:通過類定義的數據結構實例。對象包括兩個數據成員(類變量和實例變量)和方法。
2、類定義
定義一個類:
class ClassName:.... .... ....類名建議采用駝峰式命名,或者全部大寫字母
3、使用類對象方法
類對象支持兩種操作:屬性引用和實例化
屬性引用:和python中的其他語法一樣,obj.name
在類中帶__的屬性為類的私有屬性,私有屬性在類外部無法直接訪問,像__name.
class Fruit:#這是類的一個基本屬性self.number = 100def get_number(self):a = self.number + 100return a f = Fruit()print('We have {0} fruits'.format(f.number))print('We have {0} fruits'.format(f.get_number()))輸出結果:
We?have?100?fruitsWe?have?200?fruits4、構造方法
python類中有一個名為__init__()的特殊方法,叫構造方法,該方法在類進行實例化時會自動進行調用(可以用于類屬性初始化等),類似C++里面類的構造函數。
def __init__(self):self.data = []類定義了 __init__() 方法,類的實例化操作會自動調用__init__()方法。
?
class Fruit:def __init__(self): print('你已經實例化了一個對象') f = Fruit()輸出結果
你已經實例化了一個對象init_() 方法可以有參數,參數通過 init() 傳遞到類的實例化操作上。
class Complex:def __init__(self,real,image):self.r = realself.i = imagedef get_complex(self): print('complex real is %.2f , image is %.2f'%(self.r,self.i)) a = Complex(3.5,-3)a.get_complex()?
輸出結果如下:
complex real is 3.50 , image is -3.00self代表類的實例,而非類。類的方法與普通的函數只有一個特別的區別——它們必須有一個額外的第一個參數名稱, 按照慣例它的名稱是 self。但self并不是Python中的關鍵字哦。
?
不知是否可以這樣理解,self就代表的是你按照一個類實例化一個對象后的對象的地址。很像C++類中this指針class Test:
def prt(self): print(self) print(self.__class__) t = Test()t.prt()輸出:
?
<__main__.Test object at 0x0000025EC6D45608><class '__main__.Test'>5、類的方法
在類的內部,使用 def 關鍵字來定義一個方法,與一般函數定義不同,類方法必須包含參數 self, 且為第一個參數。如果不需要self傳遞參數,需要在函數前面加上@staticmethod,表示靜態方法
???????
class Complex:def __init__(self, real=None, image=None):self.r = realself.i = image def get_complex(self): print('complex real is %.2f , image is %.2f' % (self.r, self.i)) @staticmethoddef test(a, b): print('complex real is %.2f , image is %.2f' % (a, b))a = Complex(3.5, -3)a.get_complex() b = Complex()b.test(3, -2)輸出結果???????
complex real is 3.50 , image is -3.00complex real is 3.00 , image is -3.006、繼承
Python 同樣支持類的繼承,格式如下:???????
class Derivedclassname(Baseclassname): ... ...Baseclassname(基類名)必須與派生類定義在一個作用域內。除了類,還可以用表達式,基類定義在另一個模塊中時這一點非常有用:
class Fruit:????def?__init__(self,sweet):????????self.sweetness?=?sweet????def?describe(self):???? ???print('Our?fruit?has?a?sweetness?of?%.2f'%self.sweetness) class Apple(Fruit):#單繼承,繼承fruit類????def?__init__(self,sweet,color):????????self.color?=?color????????Fruit.__init__(self,sweet)????def?describe(self):#改寫基類fruit的方法????????print('Our?apple?has?a?sweetness?of?{0:.2f}%,and?color?is?{1}'.format(self.sweetness,self.color))apple = Apple(62.2,'red')apple.describe()輸出:
?
Our apple has a sweetness of 62.20%,and color is red?
多繼承
Python同樣可以繼承多個基類:
class Derivedclassname(basename1,basename2,...): ... ... ...需要注意圓括號中父類的順序,若是父類中有相同的方法名,而在子類使用時未指定,python從左至右搜索,即方法在子類中未找到時,從左到右查找父類中是否包含方法。???????
class Fruit: def __init__(self, sweet): self.sweetness = sweet def describe(self): print('Our fruit has a sweetness of %.2f' % self.sweetness)class Food: def __init__(self, uprice, num): self.unit_price = uprice self.number = num self.total_price = num * uprice def cost(self): print('You need to pay {0:.3} yuan, thank you'.format(self.total_price))class Apple(Fruit, Food): def __init__(self, sweet, color, uprice, num): self.color = color Fruit.__init__(self, sweet) Food.__init__(self, uprice, num) def describe(self): print('Our fruit has a sweetness of {0:.2f}%,and color is {1}'.format(self.sweetness, self.color))apple = Apple(62.2,'red',3.5,21)apple.describe()apple.cost()輸出:
?
Our fruit has a sweetness of 62.20%,and color is redYou need to pay 73.5 yuan, thank you7、方法重寫
如果父類方法的功能不能滿足你的需求,你可以在子類重寫你父類的方法,如果想調用已經被覆蓋的基類方法,可以用super(子類名,子類實例對象名).父類方法
class?Parent_class: def Method(self): print ('父類方法')class Child_class(Parent_class): # 定義子類 def Method(self): print ('子類方法')c = Child_class() # 子類實例化c.Method()??????????????????#?子類調用重寫方法super(Child_class,c).Method()????#用子類對象調用父類已被覆蓋的方法子類繼承父類構造函數
如果在子類中需要父類的構造方法就需要顯式地調用父類的構造方法,或者不重寫父類的構造方法。
- ?
輸出
- ?
?
如果重寫了__init__ 時,實例化子類,就不會調用父類已經定義的 __init__。
如果重寫了__init__ 時,要繼承父類的構造方法,可以使用 super 關鍵字super(子類,self).__init__(參數1,參數2,....),或者父類名稱.__init__(self,參數1,參數2,...)
8、類的私有屬性
兩個下劃線開頭,聲明該屬性為私有,像__name不能在類的外部被使用或直接訪問。在類內部的方法中使用時 self.__name。
?
class?JustCounter:?????__secretCount?=?0??#?私有變量??? publicCount?=?0??#?公開變量 def count(self): self.__secretCount += 1???? self.publicCount?+=?1???????print(self.__secretCount)counter?=?JustCounter()counter.count()counter.count()print(counter.publicCount)print(counter.__secretCount)??#?報錯,實例不能訪問私有變量 Traceback (most recent call last):File "test.py", line 16, in <module> print (counter.__secretCount) # 報錯,實例不能訪問私有變量AttributeError: 'JustCounter' object has no attribute '__secretCount'?
兩個下劃線開頭,聲明該方法為私有方法,像__private_method,只能在類的內部調用 ,不能在類的外部調用。self.___private_method。
?
class?Site: def __init__(self, name, url): self.name = name # public self.__url = url # private def who(self):??????? print('name??:?',?self.name)??????? print('url?:?',?self.__url) ????def?__foo(self):??#?私有方法????????print('這是私有方法') ????def?foo(self):??#?公共方法??????? print('這是公共方法') self.__foo()x = Site('***', 'www.xxx.com')x.who()?#?正常輸出x.foo()?#?正常輸出x.__foo()??#?報錯輸出:
'''name : ***url : www.***.com這是公共方法這是私有方法Traceback (most recent call last): File "F:\Python\Program\test.py", line 61, in <module> x.__foo() # 報錯AttributeError: 'Site' object has no attribute '__foo''''?
類的專有方法
__init__ : 構造函數,在生成對象時調用,類似C++構造函數
__del__: 析構函數,釋放對象時使用,類似C++析構函數,常用在釋放申請的內存空間
__repr__: 打印,轉換。這個個函數就是在打印類的時候,控制類輸出的字符串
?
class Name: def __init__(self, name): self.name = nameprint(Name('s'))?
'''<__main__.Name object at 0x0000023744AFD248>''' class Name: def __init__(self,name): self.name = name def __repr__(self): #控制了在打印類時候的輸出 return 'Name({!r})'.format(self.name)print(Name('s')) '''Name('s')'''?
?
__setitem__ : 每當屬性被賦值的時候都會調用該方法,因此不能再該方法內賦值 self.name = value 會死循環
__getitem__: 當訪問不存在的屬性時會調用該方法
__len__: 獲得長度,如果一個類表現得像一個list,要獲取有多少個元素,就得用len() 函數。要讓len()函數工作正常,類必須提供一個特殊方法__len__(),它返回元素的個數。
class CountList:????def?__init__(self,?*args): self.list = [x for x in args] self.count = self.__len__() ?????def?__len__(self):?????????return?len(self.list) ?????def?get_count(self): return self.counta?=?CountList(1,?2,?3,?4,?4,?5)print(a.get_count())print(len(a))???????__cmp__: 比較運算
__call__: 函數調用
__add__: 加運算
__sub__: 減運算
class MyClass: def __init__(self, height, weight): self.height = height self.weight = weight # 兩個對象的長相加,寬不變.返回一個新的類????def?__add__(self,?others): return MyClass(self.height + others.height, self.weight + others.weight) # 兩個對象的寬相減,長不變.返回一個新的類 def __sub__(self, others): return MyClass(self.height - others.height, self.weight - others.weight) # 說一下自己的參數 def intro(self):?????? print("高為",?self.height,?"?重為",?self.weight)def main(): a = MyClass(height=10, weight=5) a.intro() b = MyClass(height=20, weight=10) b.intro() c = b - a c.intro() d = a + b d.intro()if __name__ == '__main__': main()- ?
__mul__: 乘運算
__truediv__: 除運算
__mod__: 求余運算
__pow__: 乘方
同樣的。類的專有方法也可以重寫
總結
以上是生活随笔為你收集整理的Python面向对象---类的基本使用的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: Python Tensorflow神经网
- 下一篇: 使用python操作postgresql
