本文出自“阿敏其人”簡書技術(shù)博客,轉(zhuǎn)載請注明出處送滞。
文/阿敏其人
一寸谜、類的創(chuàng)建
創(chuàng)建格式
class 類名:
def 方法1(self, 參數(shù)列表):
pass
.
來個例子
class Dog:
"""這是一個狗類"""
def eat(self):
print("吃香喝辣")
# 創(chuàng)建示例
d1 = Dog();
.
.
類的屬性和方法 初探
在類里面可以直接定義 屬性 和 方法,跟其他語言類似健蕊。
__dir__
方法
在python里,我們可以通過 __dir__
查看當前實例的所有的方法和屬性踢俄。
(并不是所有的實例擁有的屬性和方法都是一樣多的缩功,待會會談到)
代碼
class Phone:
"""一個簡單的類實例"""
phoneColor = "經(jīng)典黑"
def f(self):
return 'hello'
# 實例化類
x = Phone()
# 訪問類的屬性和方法
print("Phone 類的屬性 phoneColor 為:%s" % x.phoneColor)
print("Phone 類的方法 f 輸出為: %s" % x.f())
print("Phone類的對象 x 所有的屬性和方法: %s" % x.__dir__())
.
輸出
Phone 類的屬性 i 為:經(jīng)典黑
Phone 類的方法 f 輸出為: hello
Phone 所有的屬性和方法: ['__module__', '__doc__', 'phoneColor', 'f', '__dict__', '__weakref__', '__repr__', '__hash__', '__str__', '__getattribute__', '__setattr__', '__delattr__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__init__', '__new__', '__reduce_ex__', '__reduce__', '__subclasshook__', '__init_subclass__', '__format__', '__sizeof__', '__dir__', '__class__']
Process finished with exit code 0
通過dir列出的內(nèi)容,我們的Phone的實例有一個 phoneColor 的屬性褪贵。
.
.
二掂之、關(guān)于方法
類的所有方法幾乎必帶的 self 形參
- 類的所有的方法都必須帶有一個self的形參,但是調(diào)用時不需要傳值(靜態(tài)方法和類方法除外)脆丁。
- self代表類的對象世舰,不是類!由 哪一個對象 調(diào)用的方法槽卫,方法內(nèi)的 self 就是 哪一個對象的引用跟压,在類封裝的方法內(nèi)部,self 就表示 當前調(diào)用方法的對象自己歼培。(類方法除外)
- 調(diào)用方法時震蒋,不需要傳遞 self 參數(shù)
- self 這個詞不是指定的關(guān)鍵字茸塞,換成 abcd 什么的也行,只是叫做 self 含義較好查剖。
class Test:
def showAdd(self):
print(self) # print(self) 可以打印出對象的地址
print(self.__class__) # self.__class__ 可以指向真正類
t = Test()
t.showAdd()
.
輸出
<__main__.Test object at 0x108d17e80>
<class '__main__.Test'>
self.class 可以指向真正類
.
.
init() 初始化方法
- 類的初始化會調(diào)用 init() 的特殊方法(構(gòu)造方法)钾虐,開發(fā)時經(jīng)常在定義類時重寫該方法,做初始化操作笋庄。
代碼
class Phone(object):
"""一個簡單的類實例"""
def __init__(self,brand,size):
self.brand = brand
self.size = size
# 實例化類
x = Phone("MI","5寸")
# 訪問類的屬性和方法
print("類對象 brand:%s" % x.brand)
print("類對象 size : %s" % x.size)
print("Phone類的對象對象 x 所有的屬性和方法: %s" % x.__dir__())
.
類對象 brand:MI
類對象 size : 5寸
Phone 所有的屬性和方法: ['brand', 'size', '__module__', '__doc__', '__init__', '__dict__', '__weakref__', '__repr__', '__hash__', '__str__', '__getattribute__', '__setattr__', '__delattr__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__new__', '__reduce_ex__', '__reduce__', '__subclasshook__', '__init_subclass__', '__format__', '__sizeof__', '__dir__', '__class__']
Process finished with exit code 0
初始化演示完畢效扫,需要注意的是:brand和size,是Phone類的對象的屬性直砂,不是Phone類的屬性菌仁。
.
.
類的方法的分類: 公有方法、私有方法静暂、靜態(tài)方法和類方法
公有方法
公有方法:方法名前后都帶有__济丘,比如module
定義方式
:def namemethod(self)
調(diào)用方式
:對象名.公有方法
私有方法
私有方法:私有方法:方法名只有前面帶有__,比如 __testPrivate洽蛀。
定義方式
:def __namemethod(self)
調(diào)用方式
:self._namemethod摹迷。注意:不能通過對象名直接調(diào)用。只能在屬于對象的方法中通過self調(diào)用辱士,或者在外部通過python的壓縮規(guī)則進行調(diào)用泪掀。
(后文會結(jié)合私有屬性听绳,附上例子)
類方法
類方法
可以直接通過類名調(diào)用颂碘,也可以通過類的實例訪問
靜態(tài)方法和類方法都無法訪問類實例屬性,能通過類訪問類屬于類屬性椅挣。
類方法头岔,第一個參數(shù)必須要默認類,一般習(xí)慣用cls鼠证。類方法的形參 cls峡竣,代表類本身
定義方式
:
@classmethod
def methodname(cls)
常見場景
類方法用在模擬java定義多個構(gòu)造函數(shù)的情況。
靜態(tài)方法
靜態(tài)方法
可以直接通過類名調(diào)用量九,也可以通過類的實例訪問适掰。
靜態(tài)方法和類方法都無法訪問類實例屬性,能通過類訪問類屬于類屬性荠列。
靜態(tài)方法對參數(shù)沒有要求
定義方式
:
@staticmethod
def methodname()
調(diào)用方式
:類名.方法名
常見場景
類中靜態(tài)方法方法調(diào)用靜態(tài)方法的情況类浪。
靜態(tài)方法和類方法的簡單對比
1、兩者都可以通過類對象或類名訪問肌似;靜態(tài)方法和類方法都無法訪問實例變量的费就,但可以通過類名訪問類屬性。
2川队、靜態(tài)方法和類方法力细,可以減少 創(chuàng)建多實例時 所創(chuàng)造出來的內(nèi)存空間睬澡,加快運行速度。
.
.
代碼
class Phone(object):
"""一個簡單的類實例"""
age = 18
def __init__(self,brand,size):
self.brand = brand
self.size = size
def normalMethod(self):
print("方法 normalMethod 被調(diào)用 %s" % self)
def pubTest(self):
print("公有方法 pubTest 被調(diào)用 %s" % self)
def __pubTestOther__(self):
print("公有方法 __pubTestOther__ 被調(diào)用 %s" % self)
def __privateTest(self):
print("私有方法 __privateTest 被調(diào)用 %s" % self)
pass
@staticmethod
def staticTest(): # 靜態(tài)方法不需要默認的 self 或者 cls 作為形參
print("靜態(tài)方法 staticTest 被調(diào)用")
print(Phone.age) # 靜態(tài)方法需要通過 類名.屬性 來訪問屬性
@classmethod
def classTest(cls):
print("類方法 classTest 被調(diào)用 %s" % cls)
print("類方法 訪問類的屬性 %s" % Phone.age)
# 實例化類
x = Phone("MI","5寸")
print("Phone類的對象對象 x 所有的屬性和方法: %s" % x.__dir__())
print("")
print("*"*10, "公有方法 開始", "*"*10)
x.pubTest()
print("*"*10, "公有方法 結(jié)束", "*"*10)
print("")
print("*"*10, "私有方法 開始", "*"*10)
print("私有方法無法直接通過 類對象 或者 類名 訪問")
print("*"*10, "私有方法 結(jié)束", "*"*10)
print("")
print("*"*10, "靜態(tài)方法 開始", "*"*10)
x.staticTest()
Phone.staticTest()
print("*"*10, "靜態(tài)方法 結(jié)束", "*"*10)
print("")
print("*"*10, "類方法 開始", "*"*10)
x.classTest()
Phone.classTest()
print("*"*10, "類方法 結(jié)束", "*"*10)
.
.
打用呗臁:
Phone類的對象對象 x 所有的屬性和方法: ['brand', 'size', '__module__', '__doc__', 'age', '__init__', 'normalMethod', 'pubTest', '__pubTestOther__', '_Phone__privateTest', 'staticTest', 'classTest', '__dict__', '__weakref__', '__repr__', '__hash__', '__str__', '__getattribute__', '__setattr__', '__delattr__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__new__', '__reduce_ex__', '__reduce__', '__subclasshook__', '__init_subclass__', '__format__', '__sizeof__', '__dir__', '__class__']
********** 公有方法 開始 **********
公有方法 pubTest 被調(diào)用 <__main__.Phone object at 0x107aa02e8>
********** 公有方法 結(jié)束 **********
********** 私有方法 開始 **********
私有方法無法直接通過 類對象 或者 類名 訪問
********** 私有方法 結(jié)束 **********
********** 靜態(tài)方法 開始 **********
靜態(tài)方法 staticTest 被調(diào)用
18
靜態(tài)方法 staticTest 被調(diào)用
18
********** 靜態(tài)方法 結(jié)束 **********
********** 類方法 開始 **********
類方法 classTest 被調(diào)用 <class '__main__.Phone'>
類方法 訪問類的屬性 18
類方法 classTest 被調(diào)用 <class '__main__.Phone'>
類方法 訪問類的屬性 18
********** 類方法 結(jié)束 **********
.
.
三煞聪、關(guān)于屬性
1:實例屬性:
最好在__init__
(self,...)中初始化,內(nèi)部調(diào)用時都需要加上self.
2:類屬性:
在__init__()
外初始化
類的實例或者直接通過類名都可以訪問
3:私有屬性:
1逝慧、單下劃線開頭:告訴別人這是私有屬性米绕,但是外部依然可以訪問更改
2、雙下劃線_開頭:外部不可訪問馋艺。無論是類名還是類實例栅干。
(python中沒有絕對真正的私有屬性)
.
.
實例屬性示例代碼
- 一個類的對象可以通過點語法為當前類的對象添加一個屬性,但這種方式添加的屬性只屬于這個屬于對象捐祠,是實例屬性屬性碱鳞。
代碼
class Dog:
"""這是一個狗類"""
def eat(self):
print("吃香喝辣")
dog = Dog();
print(dog.__dir__())
dog.name = "大白"
print(dog.__dir__())
# 通過 __dir__ 的打印對比,我們可以很明顯地發(fā)現(xiàn)踱蛀,dog.name = "大白" 執(zhí)行過后窿给,該對象多了一個 名為 name 的屬性,這個屬性只屬于這個實例
print(dog.name)
dog2 = Dog() # dog2并沒有 name 這個屬性
print(dog2.__dir__())
.
輸出
['__module__', '__doc__', 'eat', '__dict__', '__weakref__', '__repr__', '__hash__', '__str__', '__getattribute__', '__setattr__', '__delattr__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__init__', '__new__', '__reduce_ex__', '__reduce__', '__subclasshook__', '__init_subclass__', '__format__', '__sizeof__', '__dir__', '__class__']
['name', '__module__', '__doc__', 'eat', '__dict__', '__weakref__', '__repr__', '__hash__', '__str__', '__getattribute__', '__setattr__', '__delattr__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__init__', '__new__', '__reduce_ex__', '__reduce__', '__subclasshook__', '__init_subclass__', '__format__', '__sizeof__', '__dir__', '__class__']
大白
['__module__', '__doc__', 'eat', '__dict__', '__weakref__', '__repr__', '__hash__', '__str__', '__getattribute__', '__setattr__', '__delattr__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__init__', '__new__', '__reduce_ex__', '__reduce__', '__subclasshook__', '__init_subclass__', '__format__', '__sizeof__', '__dir__', '__class__']
Process finished with exit code 0
.
.
訪問私有屬性和私有方法 示例
代碼
class PriTest(object):
# 私有屬性
__priMem = "Jill"
# 私有方法
def __privateMethod(self):
print("i ma a private metoid")
pt = PriTest()
# 利用python的壓縮規(guī)則率拒,我們依然可以調(diào)用到 私有方法崩泡。 但是不建議這么做。
#私有屬性和方法的處理方式:在 名稱 前面加上 _類名 => _類名__名稱
pt._PriTest__privateMethod()
print(pt._PriTest__priMem)
.
輸出
i ma a private metoid
Jill
Process finished with exit code 0
.
.
END.
謝謝閱讀猬膨。