1. 程式人生 > >面向對象中的雙下方法

面向對象中的雙下方法

har instance 被調用 lex csharp 垃圾 自動 改變 **kwargs

1、__str__與__repr__方法

class Animal:
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def f(self):
        print("這是父類的方法")
class Persion(Animal):
    country = "chinese"
    def __init__(self,name,age,sex):
        Animal.__init__(self,name,age)
        self.sex = sex
    def eat(self):
        print("這是子類中的方法")
    # def __str__(self):
    #     return "這是子類中的str"
    def __repr__(self):
        return "這是子類中的repr"
a = Persion("小明",18,"sex")
print(a)
print(str(a))
print(repr(a))
print(a.__repr__())
print(a.__str__())
print(‘%s‘%a)
print(‘%r‘%a)

這兩個雙下方法可以改變字符串的顯示,打印一個對象,本質上是調用__str__方法,如果沒有找到,就找__repr__方法,再找不到,就調用父類中的,__repr_是__str__的備胎,__str__不是__repr_的,再父類中有一個__str__方法,一旦調用,就返回調用這個方法的對象的內存地址。調用__str__一共有四種方法。

2、__del__析構函數 再刪除一個對象之前進行一個收尾工作

註:此方法一般無須定義,因為Python是一門高級語言,程序員在使用時無需關心內存的分配和釋放,因為此工作都是交給Python解釋器來執行,所以,析構函數的調用是由解釋器在進行垃圾回收時自動觸發執行的。

class Persion(Animal):
    country = "chinese"
    def __init__(self,name,age,sex):
        Animal.__init__(self,name,age)
        self.sex = sex
    def eat(self):
        print("這是子類中的方法")
    # def __str__(self):
    #     return "這是子類中的str"
    def __repr__(self):
        return "這是子類中的repr"
    def __del__(self):
        print("我要開始刪除對象了")
a = Persion("小明",18,"sex")
del  a
print(a)

del既執行了這個方法,也刪除了變量,先執行__del__,在執行刪除,再刪除一個對象之前做收尾工作。

3、__call__ 對象後面加括號執行 即:對象() 或者 類()()

class Foo():
    def __call__(self, *args, **kwargs):
        print("打印call函數")
a = Foo()
a()
Foo()()

4、__new__構造函數 實例化對象

調用__init__方法之前,首先調用__new__方法,返回一個實例self ,若__new__方法沒有返回當前類cls的實力,那麽init方法不會被調用。因為類每一次實例化產生的過程都是通過__new__來控制的,所以我們可以通過__new__方法簡單的實現實例化。

通過__new__方法方法實例化一個對象,並開辟一塊地址空間,__new__方法return實例,init方法就不會被調用

class Animal:
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def f(self):
        print("這是父類的方法")
class Persion(Animal):
    country = "chinese"
    _instance = False
    def __init__(self,name,age,sex):
        Animal.__init__(self,name,age)
        self.sex = sex
        print("init方法")
    def eat(self):
        print("這是子類中的方法")
    def __new__(cls, *args, **kwargs):
        if cls._instance :
            return cls._instance
        cls._instance = object.__new__(Persion)
        return cls._instance
a = Persion("小明",18,"sex")
a.cloth = "小花襖"
print(a)
print(a.__dict__)
b = Persion("小紅",19,"nv")
print(b)
print(b.__dict__)
print(a.__dict__)

單例模式只會產生一個實例,就是第一個實例,之後的實力化,相當於對之前對象的屬性重新命名。

5、__eq__方法 父類中的eq方法默認比較的是內存地址

class Animal:
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def f(self):
        print("這是父類的方法")
class Persion(Animal):
    def __init__(self,name,age,sex):
        Animal.__init__(self,name,age)
        self.sex = sex
    def eat(self):
        print("這是子類中的方法")
    def __eq__(self,other):
        if self.name == other.name:
            return True
        else :
            return False
a = Persion("小明",18,"sex")
b =Persion("小明",43,"女")
print(a == b)

通過比較名字來判斷是不是相等

應用:100個學生記錄,其中有的名字和性別相同,年齡不同,認為名字和性別相同就是同一個人,根據這個去重

6、__delitem__ __delattr__ __setitem__ __getitem__

class Foo:
    def __init__(self,name):
        self.name=name

    def __getitem__(self, item):
        print("執行getitem方法了")
        # print(self.__dict__[item])
        return None

    def __setitem__(self, key, value):
        print("執行setitem方法了")
        self.__dict__[key]=value
    def __delitem__(self, key):
        print(‘del obj[key]時,我執行‘)
        self.__dict__.pop(key)
    def __delattr__(self, item):
        print(‘del obj.key時,我執行‘)
        self.__dict__.pop(item)

f1=Foo(‘sb‘)
f1[‘age‘]=18
f1[‘age1‘]=19
del f1.age1
del f1[‘age‘]
f1[‘name‘]=‘alex‘
print(f1.__dict__)
print(f1["agge"])

面向對象中的雙下方法