標籤:python物件導向類成員 靜態方法 類方法 普通方法
一、概述
上篇《python物件導向OOP》介紹了python物件導向的基礎初級入門部分,提到了類的定義,使用,類的三大特性;經典類,新式類在尋找時的區別等,有了前面的基礎,本文接著描述物件導向中類成員;先整體描述下,類中的成員分以下幾部分:
#類成員
#欄位(屬性):
普通欄位 屬於對象,儲存在對象中,只能通過對象訪問
靜態欄位 屬於類,儲存(一份)在類中(所有對象共用的欄位屬性),執行時可以是類訪問也可以是對象訪問
#方法:
普通方法 儲存在類中,又叫執行個體方法,首先建立對象,對象間接訪問普通方法,類也可以訪問,需要傳對象 self==>對象
靜態方法 通過加@staticmethod裝飾器變為靜態方法,儲存在類中;self可省,此時可以通過類直接調用,類似模組對函數的封裝
類方法 通過加@classmethod儲存在類中,由類直接調用,cls ==>當前類
#屬性(特性):
按方法定義 ,調用時像欄位屬性
二、類欄位屬性
class Foo: public = "isclass" #靜態欄位 def __init__(self,arg): self.name = "a" ##普通欄位 self.arg = arg ##普通欄位 def bar(self): print(self.name,self.arg) obj = Foo("hello")obj.bar()print(obj.public)print(Foo.public)
運行結果:
a hello
isclass
isclass
說明:在類中定義的屬性(欄位)我們叫靜態欄位,它不屬於對象,屬於類,好處是不管建立執行個體化多少對象,它只在記憶體中保留一份;self.xxx = xxxx這種,由於 self表示對象本身,因此儲存在對象中,屬於對象,叫普通欄位,執行個體化多少對象,記憶體中就保留多少份。靜態欄位和普通欄位,執行個體化的對象都可以調用。靜態欄位除了對象可以調用,類也可以調用。但類不能調用對象的普通欄位,因為它屬於對象。
三、類中的方法
類的方法分為普通方法,類方法 ,靜態方法 三種下面我們分別來說明:
1、普通方法(執行個體方法)
class Foo: public = "isclass" # 靜態欄位 def __init__(self,name,age): self.name = name ##普通欄位 self.age = age ##普通欄位 def bar(self,arg): print(self.name, self.age,argobj = Foo() #執行個體化出obj對象obj.bar(666) #通過obj對象調用bar普通方法Foo.bar(obj,666) #通過Foo類傳入obj對象調用bar方法
運行結果:
san 18 666
san 18 666
說明:對於普通方法,儲存在類中;執行個體對象可以直接調用(有參數就需要傳參),類可以調用方法再傳入對象,和需要的參數,效果一樣。因此對於普通方法,執行個體對象可以調用,類也可以調用,但前提都需要先執行個體化對象,要麼直接調用,要麼通過類調用把執行個體對象傳入。
2、靜態方法
class Foo: def __init__(self,name,age): self.name = name self.age = age def showinfo(self): print(self.name,self.age) @staticmethod #通過@staticmethod 把方法轉換成靜態方法 def stac(): #靜態方法時self不是必須的,加了self也並非指對象 print("static") @staticmethod def stac2(a1,a2): print(a1,a2) obj = Foo("san",18) #執行個體化出對象objobj.showinfo() #obj對象調用showinfo普通方法obj.stac() #obj調用類靜態方法stacobj.stac2(1,2) #obj調用需要傳參數的類靜態方法stac2Foo.stac() #Foo類直接調用靜態方法stacFoo.stac2(1,2) #Foo類直接調用需要傳參數的類靜態方法stac2
運行結果:
650) this.width=650;" title="靜態方法.png" alt="5018cc47687c2addef56a04913b8adc3.png-wh_" src="https://s4.51cto.com/oss/201711/18/5018cc47687c2addef56a04913b8adc3.png-wh_500x0-wm_3-wmp_4-s_2797828922.png" />
說明:靜態方法通過在方法上面添加@staticmethod裝飾器,儲存在類中;靜態方法不需要傳入self參數,即使傳入了self參數也並不像普通方法那樣代指對象本身。而只是一個普通的形參數。類靜態方法對象可調用,但主要是給類調用。相當於模組對函數的封裝。
3、類方法
Foo: (,name,age): .name = name .age = age showinfo(): (.name,.age)classmd(,arg): () (,arg)obj = Foo(,) obj.showinfo() Foo.classmd() obj.classmd()
運行結果:
650) this.width=650;" title="類方法.png" alt="52d6680299e98b4bafc8933b32bfc09c.png-wh_" src="https://s5.51cto.com/oss/201711/18/52d6680299e98b4bafc8933b32bfc09c.png-wh_500x0-wm_3-wmp_4-s_2404342322.png" />
說明:類方法的定義通過在方法前加@classmethod,儲存在類中。預設參數為cls,cls代指類本身;類可調用,對象也可調用。該傳參數時就傳。
以上為類的三種方法,他們都儲存在類中,執行個體化的對象都可以調用。
類的普通方法即執行個體方法,這是類中最常見的方法;主要是執行個體調用,在沒有執行個體的情況下類是無法調用的,調用時需要傳入執行個體和參數(如果有參數)對象.方法([參數]) == 類.方法(執行個體對象,[參數])
在類中運行而不在執行個體中啟動並執行方法,我們想讓方法不在執行個體中運行時可用類方法;主要是用於類調用,傳入的參數是類,主要用於修改和類有關的資料。在沒有執行個體情況下類可直接調用。執行個體也可以調用。
經常有一些跟類有關係的功能但在運行時又不需要執行個體和類參與的情況下需要用到靜態方法.有點類似於模組對函數的封裝。
因此我們#如果對象中需要儲存一些值,執行某功能時需要使用對象中的值,用普通方法#不需要任何對象中的值, 用靜態方法,需要修改類中的值時用類方法。
四、類中屬性
現在 我們都知道 類中的方法是對過 對象.方法([參數]) 調用的,但有時候為了簡潔明了,想把這種方式變為 對象.屬性形式擷取值,這裡就引用了類中的屬性@property,來看樣本:
class Foo(object): def __init__(self): self.name = "a" ##普通欄位 #obj.name擷取 def bar(self): #執行個體方法 obj.bar()調用 print("bar") @property #屬性或叫特性 用於執行obj.per擷取值 def per(self): return 1 @per.setter #設定值 obj.per = 值 def per(self,val): print(val) @per.deleter # 刪除值 def per(self): print(66666) obj = Foo() #執行個體化objr = obj.per #由於per方法加了@property此時通過obj.per擷取調用print(r)obj.per = 123 #@per.setter即把123傳入del obj.per #@per.deleter刪除功能,這裡類比,可以做任何想做的功能
運行結果:
650) this.width=650;" title="property.png" alt="ac407a7406aa74a223a5ae32d73568df.png-wh_" src="https://s1.51cto.com/oss/201711/18/ac407a7406aa74a223a5ae32d73568df.png-wh_500x0-wm_3-wmp_4-s_2852783540.png" />
另一種寫法:
class Foo: def f1(self): #等同於@property def f1 return 123 def f2(self,v): print(v) def f3(self): print("del") per = property(fget=f1,fset=f2,fdel=f3) #第一個參數預設是fgetobj = Foo() #執行個體化obj對象ret = obj.f1 print(ret())obj.per = 2 #傳輸值2print(obj.per) #調用obj.per == obj.f1()del obj.per #刪除obj.per == obj.f3()
運行結果:
650) this.width=650;" title="property02.png" alt="580a80164eb26e8f929f75ef0e0c1932.png-wh_" src="https://s3.51cto.com/oss/201711/18/580a80164eb26e8f929f75ef0e0c1932.png-wh_500x0-wm_3-wmp_4-s_2404413051.png" />
總結:通過@property裝飾器可以將一個方法變為類似屬性的調用形式。讓代碼看起來更簡潔。
以上為個人總結,如有錯誤之處歡迎指正交流。
本文出自 “學無止境,學以致用” 部落格,請務必保留此出處http://dyc2005.blog.51cto.com/270872/1982981
python物件導向之類成員