敢來挑戰嗎——你能想到多少種創建Python對象的方法?
下面有一個名為Point的類,這是一個最簡單也最常見的類。
class Point(object):n def __init__(self, x, y):n self.x = xn self.y = ynn @classmethodn def new_object(cls, x, y):n return cls(x, y)n
一、問題
現在有一個問題,對於這個類定義,你能想到多少種創建對象的方法?
大家先不要看答案,在腦海裡面想一下,看看自己能夠想到多少種創建對象的方法。我自認為Python掌握得非常好,看到這個問題時,也只能想到4種方法。並不是因為我漏掉了什麼重要的知識,而是因為我思維定式,沒辦法打開腦洞了。
在《Python編程實戰——運用設計模式、並發和程序庫創建高質量程序》一書中,作者給出了7種創建Python對象的方法,簡直是大開眼界。再加上我自己想到的一種方法,共有8種創建Python對象的方法。這8種創建對象的方法,一方面可以大開眼界,另一方面,也蘊含了許多Python知識。因此,這裡拿出來與大家分享。
二、答案
為了便於大家測試與學習,我對書中的例子進行了簡單的修改,以便大家能夠直接運行。8種創建對象的方法如下:
ps:知乎垃圾,貼整段代碼無法保存。完整代碼請點擊這裡。上面這段程序的執行結果如下:
~$ python create_python_object.py nPoint(1, 2)nPoint(2, 4)nPoint(3, 6)nPoint(4, 8)nPoint(5, 10)nPoint(6, 12)nPoint(7, 14)nPoint(8, 16)n
三、解釋
下面是對創建對象的8種方法的解釋說明:
- point1是按照傳統的方式創建的,也是大家最常用的方式。這種方式也稱之為靜態方式,其他方式稱之為動態方式。
- 在創建point2、point3與point4時,我們把類名當做是普通的參數傳遞給相應的函數。point2調用了存在安全隱患的eval函數。在我們的程序中,千萬不要使用這個函數。
- point3與point4原理是一樣的。在point3中,我們通過sys.modules[__name__]獲取當前模塊的所有屬性。在point4的創建中,我們直接使用globals函數獲取當前模塊中的屬性。獲取模塊的所有屬性以後,可以直接通過類的名稱獲取到Point這個類對象。獲取到類對象以後,執行類調用,就創建了一個對象。
- point5通過調用make_object函數創建對象。在這個例子中,我們將類作為一個普通的參數,傳遞給make_object函數。
- 在創建point6時,我們通過copy.deepcopy函數複製了一個已經存在的對象,並通過修改對象屬性的方式獲得了一個新的對象。
- point7涉及到的知識點是,我們可以通過object.__class__獲取到對象的類。獲取到類以後,再執行類調用,就又創建了一個新的對象。
- point8是我想到的方法,這也是比較容易想到的方式,不知道為什麼《Python編程實戰的》作者沒有想到。point8是通過Python的類方法調用來創建一個對象。在類方法調用中,Python會自動將類傳遞給方法的第一個參數。
四、結束語
在我們編寫程序時,總是應該使用最簡單的方式來創建類(第一種方法)。但是,這裡討論的創建類方法也不是沒有用處。這裡的這個例子,涉及到了模塊、對象拷貝、globals函數、類方法、__class__屬性等知識點。對於這段程序,如果大家想不到這麼多創建對象的方法,完全不是問題。但是,如果大家不看解釋說明,不能夠看懂所有創建對象的方式,則說明對Python掌握還有遺漏。從這個角度來說,討論創建Python對象的不同方法還是非常意義的,可以對Python知識進行查漏補缺。
歡迎加入MySQL+Python+大數據+NoSQL技術交流QQ群(群號:306706593)。
推薦閱讀:
※給妹子講python--15迭代環境
※Python工程師面試必備25條Python知識點
※有沒有什麼很好的 Tornado 的教材或者開源項目可以做參考的?
TAG:Python |