Python學習手冊之資料封裝、類方法和靜態方法
在上一篇文章中,我們介紹了 Python 的內部方法、操作符過載和物件生命週期,現在我們介紹 Python 的資料封裝、類方法和靜態方法。檢視上一篇文章請點選:https://www.cnblogs.com/dustman/p/10017357.html
資料封裝
面向物件程式設計的一個關鍵部分是封裝,它涉及將相關變數和函式打包到一個簡單易用的物件(類的一個例項)中。
一個相關的概念是隱藏資料,它隱藏了類的實現細節,並提供一個乾淨的標準介面。
在其它程式語言中,通常是通過私有方法和屬性完成的,這些方法和屬性阻止了對類中某些方法和屬性的外部訪問。
Python 的設計哲學略有不同。它認為 "我們都是成年人",這意味著你不應該對類的訪問設計任意的限制。因此,沒有任何方法強制方法或屬性是嚴格私有的。
但是,還是有一些方法可以阻止人們訪問類的內部私有成員。
弱私有方法和屬性在開頭只有一個下劃線。
這表明它們是私有的,不應該被外部程式碼使用。但是,它們基本上只有一個約定,並不阻止外部程式碼訪問它們。
它唯一的實際效果是,從模組匯入from module_name import * 不會匯入以單個下劃線開頭的變數。
class Name(): def __init__(self): self.__name = None def getName(self): return self.__name def setName(self, string): #判斷value的值是不是整型 if isinstance(string, str): self.__name = string else: print("Error:不是字串") m1 = Name() print(m1.getName()) m1.setName("Lisi") print(m1.getName()) m1.setName(10086) m1.__name = "WangWu" print(m1.__name)
執行結果:
>>> None Lisi Error:不是字串 WangWu >>>
上面的例子,屬性 __Name 標記為私有,但是還是可以被外部程式碼訪問。
弱私有方法和屬性的名稱開頭有雙下劃線,這意味著它們不能從類之外被訪問。
這樣做的目的並不是確保它們是私有的,而是如果又具有相同名稱的方法和屬性的子類,則可以避免出現bug 。
使用這種方法直接訪問是無法訪問的,但可以通過不同的名稱訪問。Name 類的私有方法__privatemethod 可以通過_Name__privatemethod 方法進行外部訪問。
class Name(): __name = "ZS" def print_name(self): print(self.__name) n = Name() n.print_name() print(n._Name__name) print(n.__Name)
執行結果:
>>> ZS ZS AttributeError: 'Name' object has no attribute '__Name' >>>
基本上,Python 通過內部更改名稱以包含類名來保護這些成員。
類方法
目前為止,我們所看到呼叫物件的方法都是有類的一個例項呼叫的,然後傳遞給方法的self 引數。
類方法是不同的 -- 它們由一個類呼叫,該類被傳遞給方法的cls 引數。
類方法的常見用途是工廠方法,它們使用與傳遞的類建構函式的引數不同的引數來例項化例項。
類方法被裝飾符@classmethod 標記為類方法。
class Book(): def __init__(self, title): self.title = title @classmethod def class_method_create(cls, title): book = cls(title=title) return book book1 = Book("use instance_method_create book instance:追風箏的人") book2 = Book.class_method_create("use class_method_create book instance:百年孤獨") print(book1.title) print(book2.title)
執行結果:
>>> use instance_method_create book instance:追風箏的人 use class_method_create book instance:百年孤獨 >>>
class_method_create是類方法,它不在類的例項上呼叫。而是通過類的方法呼叫,它返回類cls 的一個新物件。
從技術上將,self 和 cls 引數只是約定;它可以更改為其他任何東西。但是,這種約定被大多數人遵循。
靜態方法
靜態方法與類方法相似,只是沒有任何附加引數比如self 和cls 。它們與屬於類函式的使用方法相同。它們被靜態方法裝飾器@staticmethod 定義。
class Book(): def __init__(self, title): self.title = title @staticmethod def static_method_create(title): book = Book(title) return book book1 = Book("use instance_method_create book instance:追風箏的人") book3 = Book.static_method_create("use static_method_create book instance:活著") print(book1.title) print(book3.title)
執行結果:
>>> use instance_method_create book instance:追風箏的人 use static_method_create book instance:活著 >>>
靜態方法的行為類似於普通函式,除了不可以從類的例項中呼叫它們。
“為什麼在這個世界上,有95%的人會無法成功,而只有那少數的5%會成功,因為大多數人的心裡存在著這三個字:不可能。”