首先,什么是魔法方法呢?在python中方法名如果是 xxxx ()的,那么就有特殊的功能,因此叫做“魔法”方法。
__ init__()方法
- 當一個實例被創(chuàng)建的時候調(diào)用的初始化方法,在創(chuàng)建對象時默認調(diào)用。
- __ init __()方法中默認有一個參數(shù)名字為self,如果在創(chuàng)建對象時傳遞了2個參數(shù),那么__init __()方法除了self作為第一個形參外還需要2個形參,例如__init __(self,x,y)。
之前我們是這樣給對象添加屬性的:
class Student:
pass
stu1 = Student()
stu1.name = "張三"
stu1.age = 18
現(xiàn)在我們利用 init ()方法簡化代碼
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
stu1 = Student("張三", 18)
是不是代碼看起來簡潔多了呢
str ()方法
- 一般用于說明對象,或者自己定義一個想要輸出的結果。 當調(diào)用str()時會調(diào)用__str __(),即該對象被強制轉(zhuǎn)換成字符串類型。
- 當使用print()輸出該對象時也會調(diào)用__str __()方法,只要自己定義了__str
- __()方法,那么就會打印這個方法中return中的數(shù)據(jù)。
沒有定義__str __()方法時:
'''
遇到不懂的問題?Python學習交流群:821460695滿足你的需求,資料都已經(jīng)上傳群文件,可以自行下載!
'''
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
stu1 = Student("張三", 18)
print(stu1)
s = str(stu1)
print(s)
"""
輸出結果:
<__main__.Student object at 0x03C3BCD0>
<__main__.Student object at 0x03C3BCD0>
"""
沒有定義__str __()方法時,它默認返回該對象的內(nèi)存地址。
定義了__str __()方法是這樣的:
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return "姓名:%s\t年齡:%d"%(self.name, self.age)
stu1 = Student("張三", 18)
print(stu1)
s = str(stu1)
print(s)
"""
輸出結果:
姓名:張三 年齡:18
姓名:張三 年齡:18
"""
del ()方法
當刪除一個對象時,python解釋器會默認調(diào)用一個方法,這個方法為
del
()方法。
首先應該先了解一個概念,那就是對象的引用個數(shù)。我們需要sys模塊中的getrefcount()用來測量一個對象的引用個數(shù),返回值=實際的引用個數(shù)+1。若返回2則說明該對象的實際引用個數(shù)為1,此時有1個變量引用了該對象。
import sys
class A:
pass
a = A()
# 現(xiàn)在只有變量a引用了A類創(chuàng)建的對象
print(sys.getrefcount(a))
"""
輸出結果:
2
"""
# 那么現(xiàn)在再創(chuàng)建一個變量b,也引用a所引用的對象,那么它的引用個數(shù)就會加1,實際引用個數(shù)變成2.
b = a
print(sys.getrefcount(a))
"""
輸出結果:
3
"""
當python解釋器檢測到,這個對象的實際引用個數(shù)為0時,就會刪除這個對象,此時也就會相應的調(diào)用__del __()方法。還有一種情況就是該程序已經(jīng)全部執(zhí)行完了,那么相應的內(nèi)存會被釋放掉,它也會執(zhí)行__del __()方法。
這是程序正常執(zhí)行完的情況:
import sys
class A:
def __del__(self):
print("該對象被銷毀")
a = A()
"""
輸出結果:
該對象被銷毀
"""
還有一種是手動刪除變量引用的情況:
import sys
class A:
def __del__(self):
print("該對象被銷毀")
a = A() # 此時實際引用個數(shù)為1
b = a # 此時實際引用個數(shù)為2
print("刪除了變量a")
del a # 刪除變量a,此時實際引用個數(shù)為1
print("刪除了變量b")
del b # 刪除變量b,此時實際引用個數(shù)為0,python解釋器就會刪除該對象,即調(diào)用__del __()方法
print("程序結束")
"""
輸出結果:
刪除了變量a
刪除了變量b
該對象被銷毀
程序結束
"""
new ()方法
- __new __也是類在創(chuàng)建實例時調(diào)用的方法,它比__init __調(diào)用的時間還早。
- __new __至少要有一個參數(shù)cls,代表要實例化的類,此參數(shù)在實例化時由python解釋器自動提供。
- __new __必須要有返回值,返回實例化出來的實例,這點在自己實現(xiàn) new 時要特別注意,可以return父類 new 出來的實例,或者直接是object的 new 出來的實例。在Python3中每個類都默認繼承的object父類。
- init 有一個參數(shù)self,就是這個 new 返回的實例, init 在 new 的基礎上可以完成一些其它初始化的動作
- init 不需要返回值
class A:
def __init__(self):
print("調(diào)用了init方法")
def __new__(cls):
print("調(diào)用了new方法")
return super().__new__(cls)
a = A()
"""
輸出結果:
調(diào)用了new方法
調(diào)用了init方法
"""
拓展:可以通過重寫__new __方法,實現(xiàn)一個單例模式
代碼如下:
class A:
# 定義一個私有的類屬性,用于存儲實例化出來的對象
_isinstance = None
def __new__(cls):
print("調(diào)用了new方法")
# 判斷如果_isinstance為None,則創(chuàng)建一個實例,否則直接返回_isinstance
if not cls._isinstance:
cls._isinstance = super().__new__(cls)
return cls._isinstance
print(id(A))
print(id(A))
print(id(A))
print(id(A))
"""
輸出結果:
19888488
19888488
19888488
19888488
"""
__slots __屬性
我們都知道python是一門動態(tài)語言,可以在程序運行的過程中添加屬性。如果我們想要限制實例的屬性該怎么辦?例如,只允許對Person實例添加name和age屬性。
為了達到限制的?的,Python允許在定義class的時候,定義?個特殊的
slots
變量,來限制該class實例能添加的屬性:
class Person(object):
__slots__ = ("name", "age")
P = Person()
P.name = "?王"
P.age = 20
P.score = 100
"""
輸出結果:
Traceback (most recent call last):
File "
", line 6, in
AttributeError: 'Person' object has no attribute 'score'
"""
注意:使? slots 要注意, slots 定義的屬性僅對當前類實例起作?,對 繼承的?類是不起作?的。
更多文章、技術交流、商務合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
