Python類的內建方法

來源:互聯網
上載者:User

標籤:元類   gets   getattr   ping   none   ict   描述   相同   版本   

目錄

  • 1、new、init
  • 2、str、repr
  • 3、call
  • 4、del
  • 5、iter、next
  • 6、getitem、setitem、delitem
  • 7、getattr、setattr、delattr
  • 8、getatrribute
  • 9、enter、exit
  • 10、get、set、delete、描述符(研究中,待補充)

**(為了方便和美觀,省略了各內建方法前後的__雙底線)**

1、new、init

__new__方法是真正的類構造方法,用於產生執行個體化對象(空屬性)。重寫__new__方法可以控制對象的產生過程。
__init__方法是初始化方法,負責對執行個體化對象進行屬性值初始化,此方法必須返回None,__new__方法必須返回一個對象。重寫__init__方法可以控制對象的初始化過程。

# 使用new來處理單例模式class Student:    __instance = None    def __new__(cls, *args, **kwargs):        if not cls.__instance:            cls.__instance = object.__new__(cls)        return cls.__instance    def sleep(self):        print(‘sleeping...‘)stu1 = Student()stu2 = Student()print(id(stu1), id(stu2))  # 兩者輸出相同print(stu1 is stu2)  # True

個人感覺,__new__一般很少用於普通的業務情境,更多的用於元類之中,因為可以更底層的處理對象的產生過程。而__init__的使用情境更多。

2、str、repr

兩者的目的都是為了顯式的顯示對象的一些必要資訊,方便查看和調試。__str__print預設調用,__repr__被控制台輸出時預設調用。即,使用__str__控制使用者展示,使用__repr__控制調試展示。

# 預設所有類繼承object類,object類應該有一個預設的str和repr方法,列印的是對象的來源以及對應的記憶體位址class Student:    def __init__(self, name, age):        self.name = name        self.age = agestu = Student(‘zlw‘, 26)print(stu)  # <__main__.Student object at 0x0000016ED4BABA90>
# 自訂str來控制print的顯示內容,str函數必須return一個字串對象# 使用repr = str來偷懶控制台和print的顯示一致class Student:    def __init__(self, name, age):        self.name = name        self.age = age    def __str__(self):        return f‘{self.__class__}, {self.name}, {self.age}‘        __repr__ = __str__stu = Student(‘zlw‘, 26)print(stu)  # <class ‘__main__.Student‘>, zlw, 26
3、call

__call__方法提供給對象可以被執行的能力,就像函數那樣,而本質上,函數就是對象,函數就是一個擁有__call__方法的對象。擁有__call__方法的對象,使用callable可以得到True的結果,可以使用()執行,執行時,可以傳入參數,也可以傳回值。所以我們可以使用__call__方法來實現執行個體化對象作為裝飾器:

# 檢查一個函數的輸入參數個數, 如果調用此函數時提供的參數個數不符合預定義,則無法調用。# 單純函數版本裝飾器def args_num_require(require_num):    def outer(func):        def inner(*args, **kw):            if len(args) != require_num:                print(‘函數參數個數不符合預定義,無法執行函數‘)                return None            return func(*args, **kw)        return inner    return outer@args_num_require(2)def show(*args):    print(‘show函數成功執行!‘)show(1)  # 函數參數個數不符合預定義,無法執行函數show(1,2) # show函數成功執行!show(1,2,3)  # 函數參數個數不符合預定義,無法執行函數
# 檢查一個函數的輸入參數個數,# 如果調用此函數時提供的參數個數不符合預定義,則無法調用。# 執行個體對象版本裝飾器class Checker:    def __init__(self, require_num):        self.require_num = require_num    def __call__(self, func):        self.func = func        def inner(*args, **kw):            if len(args) != self.require_num:                print(‘函數參數個數不符合預定義,無法執行函數‘)                return None            return self.func(*args, **kw)        return inner@Checker(2)def show(*args):    print(‘show函數成功執行!‘)show(1)  # 函數參數個數不符合預定義,無法執行函數show(1,2) # show函數成功執行!show(1,2,3)  # 函數參數個數不符合預定義,無法執行函數
4、del

__del__用於當對象的引用計數為0時自動調用。
__del__一般出現在兩個地方:1、手工使用del減少對象引用計數至0,被記憶體回收處理時調用。2、程式結束時調用。
__del__一般用於需要聲明在對象被刪除前需要處理的資源回收操作

# 手工調用del 可以將對象引用計數減一,如果減到0,將會觸發記憶體回收class Student:    def __del__(self):        print(‘調用對象的del方法,此方法將會回收此對象記憶體位址‘)stu = Student()  # 調用對象的__del__方法回收此對象記憶體位址del stuprint(‘下面還有程式其他代碼‘)
class Student:    def __del__(self):        print(‘調用對象的del方法,此方法將會回收此對象記憶體位址‘)stu = Student()  # 程式直接結束,也會調用對象的__del__方法回收地址
5、iter、next

這2個方法用於將一個對象類比成序列。內建類型如列表、元組都可以被迭代,檔案對象也可以被迭代擷取每一行內容。重寫這兩個方法就可以實現自訂的迭代對象。

# 定義一個指定範圍的自然數類,並可以提供迭代class Num:    def __init__(self, max_num):        self.max_num = max_num        self.count = 0            def __iter__(self):        return self    def __next__(self):        if self.count < self.max_num:            self.count += 1            return self.count        else:            raise StopIteration(‘已經到達臨界‘)        num = Num(10)for i in num:    print(i)  # 迴圈列印1---10
6、getitem、setitem、delitem

重寫此系列方法可以類比對象成列表或者是字典,即可以使用key-value的類型。

class StudentManager:    li = []    dic = {}    def add(self, obj):        self.li.append(obj)        self.dic[obj.name] = obj    def __getitem__(self, item):        if isinstance(item, int):            # 通過下標得到對象            return self.li[item]        elif isinstance(item, slice):            # 通過切片得到一串對象            start = item.start            stop = item.stop            return [student for student in self.li[start:stop]]        elif isinstance(item, str):            # 通過名字得到對象            return self.dic.get(item, None)        else:            # 給定的key類型錯誤            raise TypeError(‘你輸入的key類型錯誤!‘)class Student:    manager = StudentManager()    def __init__(self, name):        self.name = name        self.manager.add(self)    def __str__(self):        return f‘學生: {self.name}‘    __repr__ = __str__stu1 = Student(‘小明‘)stu2 = Student(‘大白‘)stu3 = Student(‘小紅‘)stu4 = Student(‘胖虎‘)# 當做列表使用print(Student.manager[0])  # 學生: 小明print(Student.manager[-1])  # 學生: 胖虎print(Student.manager[1:3])  # [學生: 大白, 學生: 小紅]# 當做字典使用print(Student.manager[‘胖虎‘])  # 學生: 胖虎
7、getattr、setattr、delattr

當使用obj.x = y的時候觸發對象的setattr方法,當del obj.x的時候觸發對象的delattr方法。
當嘗試訪問對象的一個不存在的屬性時 obj.noexist 會觸發getattr方法,getattr方法是屬性尋找中優先順序最低的。
可以重寫這3個方法來控制對象屬性的訪問、設定和刪除。
**特別注意:如果定義了getattr,而沒有任何代碼(即只有pass),則所有不存在的屬性值都是None而不會報錯,可以使用super().__getattr__()方法來處理**

class Student:    def __getattr__(self, item):        print(‘訪問一個不存在的屬性時候觸發‘)        return ‘不存在‘    def __setattr__(self, key, value):        print(‘設定一個屬性值的時候觸發‘)        # self.key = value  # 這樣會無限迴圈        self.__dict__[key] = value    def __delattr__(self, item):        print(‘刪除一個屬性的時候觸發‘)        if self.__dict__.get(item, None):            del self.__dict__[item]stu = Student()stu.name = ‘zlw‘  # 設定一個屬性值的時候觸發print(stu.noexit)  # 訪問一個不存在的屬性時候觸發 , 返回‘不存在‘del stu.name  # 刪除一個屬性的時候觸發
8、getatrribute

這是一個屬性訪問截斷器,即,在你訪問屬性時,這個方法會把你的訪問行為截斷,並優先執行此方法中的代碼,此方法應該是屬性尋找順序中優先順序最高的。
屬性尋找順序:
執行個體的getattribute-->執行個體對象字典-->執行個體所在類字典-->執行個體所在類的父類(MRO順序)字典-->執行個體所在類的getattr-->報錯

class People:    a = 200class Student(People):    a = 100    def __init__(self, a):        self.a = a    def __getattr__(self, item):        print(‘沒有找到:‘, item)    def __getattribute__(self, item):        print(‘屬性訪問截斷器‘)        if item == ‘a‘:            return 1        return super().__getattribute__(item)stu = Student(1)print(stu.a)  # 1
9、enter、exit

這兩個方法的重寫可以讓我們對一個對象使用with方法來處理工作前的準備,以及工作之後的清掃行為。

class MySQL:    def connect(self):        print(‘啟動資料庫連接,申請系統資源‘)    def execute(self):        print(‘執行sql命令,操作資料‘)    def finish(self):        print(‘資料庫連接關閉,清理系統資源‘)    def __enter__(self):  # with的時候觸發,並賦給as變數        self.connect()        return self    def __exit__(self, exc_type, exc_val, exc_tb):  # 離開with語句塊時觸發        self.finish()with MySQL() as mysql:    mysql.execute()    # 結果:# 啟動資料庫連接,申請系統資源# 執行sql命令,操作資料# 資料庫連接關閉,清理系統資源
10、get、set、delete、描述符(研究中,待補充)

Python類的內建方法

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.