標籤:

敢來挑戰嗎——你能想到多少種創建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 |