這裡就不再講面向對象的相關概念知識或者與面向過程的比較了,直接進入類的學習 1.類的創建 2.封裝 3.繼承 子類可以對父類的方法進行重寫,子類調用父類的方法使用super(子類名,self),self永遠是執行該方法的調用者 python支持多繼承 多繼承中子類調用父類方法的尋找方法是按照父類聲明 ...
這裡就不再講面向對象的相關概念知識或者與面向過程的比較了,直接進入類的學習
1.類的創建
class people: def __init__(self):#構造函數 pass sfencs=people()#類的實例
2.封裝
class people: def __init__(self,name,age): self.name=name self.age=age sfencs=people("sfencs",19) print("%s is %d"%(sfencs.name,sfencs.age))
3.繼承
class father: def __init__(self): self.a = 1 self.b = 2 def me(self): print("i am father") print(self)#<__main__.son object at 0x000001F7DFA11128> class son(father): def __init__(self): super().__init__() super(son,self).me()#執行父類的me方法,但self是people def me(self): print("i am son") people=son() print(people.a)#1 people.me()#i am son
子類可以對父類的方法進行重寫,子類調用父類的方法使用super(子類名,self),self永遠是執行該方法的調用者
python支持多繼承
class father1: def __init__(self): self.a = 1 self.b = 2 def me(self): print("i am father1") class father2: def __init__(self): self.c = 3 self.d = 4 def me(self): print("i am father2") class son(father1,father2): def __init__(self): father1.__init__(self) father2.__init__(self) super(son,self).me()#i am father1 def me(self): print("i am son") people=son() print(people.c)#3 people.me()#i am son
多繼承中子類調用父類方法的尋找方法是按照父類聲明的順序從左到右,從下到上查找,一直查找到最高級的父類,但是如果不同的父類繼承於同一個父類,
那麼這個相當於根的父類為最後再去查找
4.多態
python原生多態,不像java,c++那樣必須在方法的形參處申明類型
5.靜態欄位與靜態方法
sex="male"為靜態欄位,可以通過對象訪問 也可以通過類訪問
self.name=name self.age=age 為普通欄位只能通過對象訪問
class people: sex="male" def __init__(self,name,age): self.name=name self.age=age sfencs=people("sfencs","19") print(sfencs.name) print(sfencs.sex) print(people.sex)
靜態方法可以通過對象訪問 也可以通過類訪問,聲明靜態方法的方式為@staticmethod
class people: sex="male" def __init__(self,name,age): self.name=name self.age=age @staticmethod def func(): print("這是靜態方法") sfencs=people("sfencs","19") sfencs.func() people.func()
類方法也可以通過對象訪問 也可以通過類訪問,聲明類方法的方式為@classmethod,類方法的參數為類
class people: sex="male" def __init__(self,name,age): self.name=name self.age=age @classmethod def func(cls): print("這是類方法") print(cls)#<class '__main__.people'> sfencs=people("sfencs","19") sfencs.func() people.func()
6.屬性
屬性定義的時候像方法,使用的時候像欄位,使用@property聲明,這樣就可以使sfencs.func有對應的值
class people: def __init__(self,name,age): self.name=name self.age=age @property def func(self): return 1 sfencs=people("sfencs","19") print(sfencs.func)#1
既然要偽裝成欄位,那麼不僅僅是能夠有對應的值,也應該能夠為它賦值,將它刪除等操作
class people: def __init__(self,name,age): self.name=name self.age=age @property def func(self): return 1 @func.setter def func(self,val): print(val) @func.deleter def func(self): print("del") sfencs=people("sfencs","19") print(sfencs.func)#1 sfencs.func=123 del sfencs.func
@func.setter為設置賦值的方法,@func.deleter為刪除設置的方法。
經過這些設置之後,看似func成立一個欄位,有了相應的特點,但其實這些特點都是假的。這三種方式只是3中對應關係,只是使用時是模仿欄位操作,但真實操作是由
自己規定的,del並不能真的刪除,而只是按照你所寫的方法做相應的動作。
除此之外屬性還有一種設置方式
class people: def __init__(self,name,age): self.name=name self.age=age def f1(self): return 1 def f2(self,val): print(val) def f3(self): print("del") func=property(fget=f1,fset=f2,fdel=f3,doc="描述") sfencs=people("sfencs","19") print(sfencs.func)#1 sfencs.func=123 del sfencs.func
只是方式改變了,效果還一樣,不多說了。
7.成員修飾符
這裡就指將成員聲明為私有的
class people:
def __init__(self,name,age):
self.name=name
self.__age=age
def getage(self):
return self.__age
sfencs=people("sfencs","19")
#print(sfencs.__age)私有成員不能直接通過對象來拿
print(sfencs.getage())#19
當然也有私有方法
class people: def __init__(self,name,age): self.name=name self.__age=age def getage(self): return self.__age def __fun(self): print("這是私有方法") def func(self): self.__fun() sfencs=people("sfencs","19") #print(sfencs.__age)私有成員不能直接通過對象來拿 print(sfencs.getage()) #sfencs.__fun() sfencs.func()
在繼承當中,私有成員與方法是不能被子類繼承的
8.特殊成員方法
__init__
構造方法,這個不用過多解釋
__del__
析構方法,當對象在記憶體中被釋放時,自動觸發執行
def __del__(self): pass
__call__
對象後面加括弧,觸發執行
class people: def __init__(self,name,age): self.name=name self.__age=age def __call__(self,a,b): print("__call__") print(a,b) sfencs=people("sfencs",19) sfencs(1,2)
__int__
調用int(對象)時使用的方法
class people: def __init__(self,name,age): self.name=name self.__age=age def __int__(self): return 10 sfencs=people("sfencs",19) data=int(sfencs) print(data)#10
__str__
那麼在列印 對象 時,預設輸出該方法的返回值
class people: def __init__(self,name,age): self.name=name self.__age=age def __str__(self): return "hello world" sfencs=people("sfencs",19) print(sfencs)#hello world
__add__
兩個對象相加執行該方法
class people: def __init__(self,name,age): self.name=name self.age=age def __add__(self,other): return self.age+other.age sfencs=people("sfencs",19) Tom=people("Tom",20) print(sfencs+Tom)#39
__dict__
查看類或對象中的所有成員
class people: sex="male" def __init__(self,name,age): self.name=name self.age=age sfencs=people("sfencs",19) print(sfencs.__dict__)#{'name': 'sfencs', 'age': 19} print(people.__dict__) #{'__module__': '__main__', 'sex': 'male', '__init__': <function people.__init__ at 0x000001B6C6F2C2F0>, '__dict__': <attribute '__dict__' of 'people' objects>, '__weakref__': <attribute '__weakref__' of 'people' objects>, '__doc__': None}
__getitem__、__setitem__、__delitem__
用於索引操作,如字典。以上分別表示獲取、設置、刪除數據
class people: def __init__(self,name,age): self.name=name self.age=age def __getitem__(self, key): print('__getitem__', key) return 2 def __setitem__(self, key, value): print('__setitem__', key, value) def __delitem__(self, key): print('__delitem__', key) sfencs=people("sfencs",19) sfencs["one"]=1#__setitem__ one 1 print(sfencs["one"])#__getitem__ one 2 del sfencs["one"]#__delitem__ one
__iter__
之所以列表、字典、元組可以進行for迴圈,是因為類型內部定義了 __iter__class people: def __init__(self,list): self.list=list def __iter__(self): return iter(self.list) sfencs=people([1,2,3,4,5]) for i in sfencs: print(i)
__module__ 和 __class__
表示當前操作的對象在那個模塊
表示當前操作的對象的類是什麼class people: def __init__(self,name,age): self.name=name self.age=age sfencs=people("sfencs",19) print(sfencs.__module__)#__main__ print(sfencs.__class__)#<class '__main__.people'>
9.類的另一種創建方式
def f(self): print(self.name,self.age) def __init__(self,name,age): self.name = name self.age = age people = type('people',(object,),{'func':f, '__init__':__init__}) sfencs=people("sfencs",19) sfencs.func()
這種方式可以看出,類也是一種對象,是type類型的對象
我們可以從下麵這張圖看出類的實際創建過程
10.反射
反射可以通過字元串的方式來找到對象中的變數或方法
反射有4個方法getattr() hasattr() setattr() delattr()
class people: def __init__(self,name,age): self.name=name self.age=age sfencs=people("sfencs",19) data1=getattr(sfencs,"name") print(data1)#sfencs data2=hasattr(sfencs,"age") print(data2)#True setattr(sfencs,"age",20) print(sfencs.age)#20 delattr(sfencs,"age") data3=hasattr(sfencs,"age") print(data3)#False
python一切事物皆是對象,模塊同樣也支持反射來操作
11.單例模式
對象也叫實例,單例模式表示該類只有一個對象
class ConnectPool: __instatnce=None @staticmethod def get_instance(): if ConnectPool.__instatnce: return ConnectPool.__instatnce else: ConnectPool.__instatnce = ConnectPool() return ConnectPool.__instatnce obj =ConnectPool.get_instance() print(obj)#<__main__.ConnectPool object at 0x000002523F0174E0> obj1 =ConnectPool.get_instance() print(obj1)#<__main__.ConnectPool object at 0x000002523F0174E0> print(obj1==obj)#True