Python類中__del__()、__call__()、__repr__()、__new__()、__hash__()方法

小小程序员ol發表於2024-08-10

1.__del__()

銷燬魔術方法
觸發時機:當一個物件在記憶體中被銷燬的時候自動執行
引數:至少有一個 self,
接收物件 返回值:無
作用:在物件銷燬的時候做一些操作
注意:程式自動呼叫此方法,不需要我們手動呼叫。

class Cat:
    def __init__(self,name):
        print("--init--")
        self.name = name

    def __str__(self):
        print("--str--")
        return self.name

    def __del__(self):
        print("這是del方法")  #物件一旦被銷燬,自動觸發此方法

cat1 = Cat("Tom")
print(cat1)
print("最後一行程式碼")
# --init--
# --str--
# Tom
# 最後一行程式碼
# 這是del方法
class Cat:
    def __del__(self):
        print('----del-----')

def func():
    cat = Cat()
    return cat   #即使有返回值,但函式外部沒有變數接受,出了函式物件依然會被銷燬
ret =func()
print("最後一行程式碼")

# 最後一行程式碼
# ----del-----

2.__call__()

方法__call__():可以讓類的例項具有類似於函式的行為,進一步模糊了函式和物件之間的概念
使用方式:物件後面加括號,觸發執行。

即:物件()或者 類()()

class Cat:
    def eat(self):
        print("吃貓糧")
    def __call__(self, *args, **kwargs):
        print("--call方法--")

cat = Cat()
cat.eat()
cat()
Cat()()

# 吃貓糧
# --call方法--
# --call方法--

#__call__方法實現斐波那契  1,1,2,3,5,新增到列表中

class Fib:
    def __call__(self, n):
        self.list = []
        a = 1
        b = 1
        for i in range(1,n+1):
            self.list.append(a)
            a,b = b,a+b
        return self.list

fib =Fib()
print(fib(5))


def fib1(n):
    x=[]
    if n==1 or n==2:
        return 1
    return fib1(n-2)+fib1(n-1)

print(fib1(5))
print(fib1(4))

# [1, 1, 2, 3, 5]
# 5
# 3

3.__repr__()

__repr__():改變物件的字串顯示

  • 此方法是 __str__()的備胎,如果找不到__str__()就會找__repr__()方法。
  • %r預設呼叫的是__repr()方法,如果是字串會預設加上''
  • repr()方法預設呼叫__repr__()方法
class Person:
    def __init__(self,name,age):
        self.name = name
        self.age = age

    def __str__(self):
        return str(self.__dict__)

    def __repr__(self):
        return 'name:%s--age:%d'%(self.name,self.age)


per = Person('johnson',18)
print(per)

string ='zhou'
print("大家好,我叫%s"%string)
print("大家好,我叫%r"%string)

# %s 預設呼叫str方法,%r預設呼叫repr方法
print("大家好,我叫%r"%per)
print("大家好,我叫%s"%per)

# {'name': 'johnson', 'age': 18}
# 大家好,我叫zhou
# 大家好,我叫'zhou'
# 大家好,我叫name:johnson--age:18
# 大家好,我叫{'name': 'johnson', 'age': 18}

4.__new__()方法

觸發機制:在例項化對時觸發
引數:至少一個cls接收當前類
返回值:必須返回一個物件例項 作用:例項化物件
注意:例項化物件 Object 類底層實現,其他類繼承了Object的__new__才能夠例項化物件
沒事別碰這個魔術方法,先觸發__new__()才觸發__init__

class Cat:
    def __init__(self):
        print('--init--')
    def __new__(cls, *args, **kwargs):
        print('---new---')
        return object.__new__(cls)  #成功建立了物件,但一出函式物件就被銷燬
    def __del__(self):
        print('--del--')

    def __str__(self):
        return '--str--'

def func():
    cat = Cat()
    print(cat)
    return cat

ret = func()
print('最後一行程式碼------')

# ---new---
# --init--
# --str--
# 最後一行程式碼------
# --del--
class Shopping:
    __instance = None

    def __new__(cls, *args, **kwargs):
        if cls.__instance==None:
            cls.__instance = object.__new__(cls)
            return cls.__instance
        else:
            return cls.__instance

shop1 = Shopping()
shop2 = Shopping()
print(id(shop1),id(shop2))
print(shop1,shop2)
shop3 = Shopping()
print(id(shop3))

# 1395248497888 1395248497888
# <__main__.Shopping object at 0x00000144DB4A84E0> <__main__.Shopping object at 0x00000144DB4A84E0>
# 1395248497888

5.__hash__()

雜湊(hash)也翻譯叫雜湊。hash演算法,是將一個不定長的輸入,透過hash函式變換成一個定長的輸出,即雜湊值
在python中,有內建的雜湊函式hash(),返回一個物件(數字、字串,不能直接用於list,set,dict)的雜湊值

set1 ={1,2,3}
dic = {'a':1}
# print({[1]:1}) # TypeError: unhashable type: 'list'

string = 'a'
print(hash(string))
print(hash((1,3)))
# 8878686175204649982
# 3713081631933328131

1.自定義物件能不能新增到集合中呢? 能預設呼叫父類的__hash____eq__
2.object的hash值是怎麼算的呢? id是hash的16倍
3.自定義物件新增到集合中,一般認為兩個物件的屬性值相同就是同一個物件 --自定義計算規則
4.注意:如果只定義了__eq__方法,沒有定義__hash__方法,__hash__方法會隱式設定成None

#學習中遇到問題沒人解答?小編建立了一個Python學習交流群:531509025
class Person:
    def __init__(self,num):
        self.num = num

p1 =Person(1)
p2 =Person(2)
p3 =Person(3)
list =[p1,p2,p3]
set(list)
print(id(p1))
print(hash(p1))

# 2424376266626597764
# 3713081631933328131
# 2187348381144
# -9223371900145501987
class Person:
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def __eq__(self,other):
        print("%s呼叫了eq方法"%self.name,self.age)
        return self.__dict__==other.__dict__
    def __hash__(self):
        print("%s呼叫了hash方法"%self.name)
        return hash(self.name)
p1 = Person('johnson',18)
p2 = Person("may",11)
p3 = Person('johnson',18)
print(id(p1),id(p2),id(p3))
set1 = {p1,p2,p3}
print(p1==p3)

# 2744803718088 2744803718032 2744803717976
# johnson呼叫了hash方法
# may呼叫了hash方法
# johnson呼叫了hash方法
# johnson呼叫了eq方法 18
# johnson呼叫了eq方法 18
# True

相關文章