使用Django做web開發的時候遇到了這樣一個問題,我想創建一個分支線程定時爬去某網站的信息,首先我就想到了使用單例模式,但是Python的單例模式并不像java那樣一個static就完事了,需要使用不同的機制來實現,在網上找了幾篇博客弄明白大概怎么回事,在這里跟大家分享一下我的理解:
首先,因為只有繼承了object的類才能定義__new__方法,所以我們要創建一個類,并且讓它繼承于object,這樣我們就可以對其__new__方法進行定義了。
class Student(object):
要知道,雖然__new__方法接受的參數和__init__一樣,但__init__是在類實例創建之后調用,而 __new__方法正是創建這個類實例的方法,所以,當我們創建一個類的時候,編譯器會先執行__new__方法,再執行__init__方法。
下邊我們定義__new__方法:
def __new__(cls, name, height):
print('class.__new__called')
if not hasattr(cls, '_instance'): # hasattr(a,b)方法是判斷a里邊有沒有b,在這里就是判斷cls(本類)里邊是否存在名為'_instance'的變量
cls._instance = super(Student, cls).__new__(cls)
return cls._instance
乍一看您可能會有些疑惑,它的原理其實是這樣的:
每次調用__new__方法,都會判斷一次本類有沒有實例化對象產生過,沒有的話,就創建一個,如果有的話,就返回以前創建過的那個對象,并將新的參數賦給原來的實例,對其進行更新。
(哈哈,是不是感覺和java的單例就有些相似了呢~)
if not hasattr(cls, '_instance'):
↑ 這行代碼就是判斷此類有無實例生成過。
cls._instance = super(Student, cls).__new__(cls)
↑ 沒有的話就讓父類生成
return cls._instance
↑ 最終都返回這個類的_instance實例化對象。
?
完整代碼如下
class Student(object):
def __new__(cls, name, height):
print('class.__new__called')
if not hasattr(cls, '_instance'): # hasattr(a,b)方法是判斷a里邊有沒有b,在這里就是判斷cls(本類)里邊是否存在名為'_instance'的變量
cls._instance = super(Student, cls).__new__(cls)
return cls._instance
def __init__(self, name, height):
print('class,__init__called')
self.name = name
self.height = height
def __str__(self):
return 'The height of student %s is %s' %(self.name, self.height)
if __name__ == '__main__':
xiaoming = Student('xiaoming', 111)
print(xiaoming)
jack = Student('Jack', 188)
print(jack)
print(xiaoming)
print(id(xiaoming))
print(id(jack))
最后的幾行代碼是用來測試的,輸出結果如下:
class.__new__called
class,__init__called
The height of student xiaoming is 111
class.__new__called
class,__init__called
The height of student Jack is 188
The height of student Jack is 188
2746489404608
2746489404608
重點注意最后三行測試結果,我們新創建的對象Jack將xiaoming覆蓋了,Jack和xiaoming此時指向的都是同一塊內存,所以print(jack) 和print(xiaoming)輸出的結果是一樣的,而最后兩行測試結果更加證明了這一點。
以上就是給大家分享的內容,小菜一枚,不足之處敬請拍磚(*?▽?*)
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
