1. 程式人生 > >Python基礎(面向物件程式設計)

Python基礎(面向物件程式設計)

 

 

 

類的內建方法

 

補充:

其實比如str()這個內建函式,都是在內部呼叫__str__方法。

之所以提供str()這種方法大概是更簡潔吧,有興趣的可以去看一下原始碼。

str(123456)實際上是123456.__str__()

例項:

    a = 123456

    b = str(123456)

    c = a.__str__

    print(b) # 輸出123456,看不出是字串型別,你可以type()下

    print(c) # 輸出一個記憶體地址,也就是存放這個字串的記憶體地址

    print(c()) # 輸出123456,用一個記憶體地址加上一個括號就是執行

    print(repr(b)) # 利用repr方法輸出 '123456',可以看出是字串型別,同時你也可以type()

    print(repr(c())) # 同上,輸出 '123456'

 

__str__

 

class A:

    def __str__(self):

        return '我是__str__方法'

a = A()

print(a)

輸出:我是__str__方法

你會覺得不可思議吧,但是確確實實是這樣,當我們輸出a的時候,實際上是輸出a.__str__()方法,友誼之前我們沒有寫這個方法,所以就會呼叫object中的__str__方法,因為所有沒有繼承的類,預設是繼承object類的,在子類中沒有找到__str__方法就會去父類object中找。

領取福利加python程式語言學習QQ群 515267276

列表例項化輸出:

list = [1,2,3,4,5]

print(list)

#那麼這裡為什麼會直接輸出一個列表,而不是一個記憶體地址,實際上就是重構了__str__方法。

注:返回值必須為字串型別

 

__repr__

 

class Person:

    def __init__(self,name):

        self.name = name 

    def __repr__(self):

        return self.name

p = Person('張三')

print(repr(p)) # 輸出 張三

print('我的名字是%r'%p) # 輸出 我的名字是張三 %r就是呼叫的__repr__()方法,同理%s?你應該懂吧。如果我們不寫repr方法,它就會呼叫父類的方法,會輸出一個記憶體地址。

注:當我們在類中寫了repr方法,沒有寫str方法,我們再次輸出str(Person)他不會輸出記憶體地址,會輸出repr中的內容,我們理解為他找不到str方法就會找repr方法,repr方法再沒有就會輸出記憶體地址,但是反過來不行。(莫名的備胎)這個repr方法也必須返回字串。

 

__del__

 

class A:

    def __init__(self,name):

        self.name = name

    def __del__(self):

        print('執行__del__方法')

a = A('張三')

del a.name   

print(a.name)     

輸出:

'A' object has no attribute 'name'

執行__del__方法

報錯了,說明刪除了name這個屬性,並且執行力__del__中的方法。和上面兩個不一樣。

注:放我們呼叫完這個一會執行__del__方法,但是沒有刪除變數。python這個方法內部有個引用計數機制,

當計數為0的時候,就會刪除這個屬性。來釋放記憶體。

例項:

class A:

    def __init__(self,name):

        self.name = name

    def __del__(self):

        print('執行__del__方法')

a = A('張三')

import time

time.sleep(1)

print(a.name) 

輸出:

張三

執行__del__方法    

可以看到,我們並沒有呼叫__del__方法,但是再呼叫完之後會自動呼叫這個方法。並且看一下執行順序,也就是說,先輸出,再呼叫__del__方法。也就是說先執行__del__中的方法,再進行刪除,也就是說我們可以在__del__寫一些收尾工作,比如f.close()。

 

__call__

 

class A:

    def __call__(self):

        print('執行了__call__方法')

a = A()

a()

輸出:執行了__call__方法

也就是a()就是執行了__call__方法。

 

__getitem__

 

class A:

    def __init__(self,name,age):

        self.name = name

        self.age = age

    def __getitem__(self,item):

        return self.__dict__[item]

a = A('張三',18)

print(a['name'])

輸出:張三

我們例項化之類後,a['name'],就是呼叫內建方法__getitem__中的內容。

 

__setitem__

 

class A:

    def __init__(self,name,age):

        self.name = name

        self.age = age

    def __setitem__(self,key,value):

        self.__dict__[key] = value

a = A('張三',18)

a['sex'] = '男'

print(a.sex)

輸出:男

也同樣,當我們a['sex'] = '男'的時候,呼叫的是 __setitem__方法。

 

__delitem__

 

class A:

    def __init__(self,name,age):

        self.name = name

        self.age = age

    def __delitem__(self,key):

        del self.__dict__[key]

a = A('張三',18)

del a['name']

這樣就刪除了,其實我會覺得像刪除不是有方法嗎,這種方法是以將物件以字典的形式查,那麼對於字典和列表你可能又有了新的認識。在object中對應的是__delattr__方法。

 

__new__

 

我們知道__init__是在例項化的時候就會執行,在他之前會執行__new__方法。 

class A:

    def __init__(self,name,age):

        self.name = name

        self.age = age

    def __new__(cls,*args,**kwargs):

        return object.__new__(A,*args,**kwargs)

__new__可以決定呼叫哪個類的_init_方法,如果有兩個類,並且是繼承關係,就可以選擇呼叫父類的__init__方法,__init__的self就是__new__例項化的結果。有興趣的可以去了解一下。

 

__eq__

 

class A:

    def __init__(self,name):

        self.name =name

    def __eq__(self,other):

        return self == other

a = A('張三')

b = A('張三')

print(a==b)

返回False,==是呼叫了__eq__方法,修改成:

def __eq__(self,other):

    return True

就會返回True,但是也不能這樣寫是吧,我們判斷名字相等就讓他返回True

def __eq__(self,other):

    if self.name == other.name:

        return True

    else:

        return False

即可。

 

__hash__

 

在hash()一個類的時候,就會執行__hash__方法。就不多說了。

領取福利加python程式語言學習QQ群 515267276