我嘗試從某些OpenSource GitHub項目中瞭解以下代碼。有一個課程沒有__init__
,但有一個__new__
方法。該代碼給出:__new__和屬性
class Node(object):
#pylint: disable=W0404
#Singleton-Pattern
_instances = dict()
def __new__(cls, name=None):
""" Instanciates a node from a file, and (name=None) creates a new node
Caution: Filenames are always given relative to the root-dir
When no name is given, a new node is created. """
if(name!=None and cls._instances.has_key(name)):
return(cls._instances[name])
if(name==None): # a new node, lets find a name
for i in itertools.count(0):
name = "node%.4d"%i
if(cls._instances.has_key(name)): continue# new nodes might not been saved, yet
if(path.exists("./nodes/"+name)): continue
break
self = object.__new__(cls)
cls._instances[name] = self
#actuall init-code
from ZIBMolPy.pool import Pool #avoids circular imports
self._pool = Pool() #Pool is a singleton
self._name = name
self._tmp = Store() #for thing that need to be stored temporarly
self._obs = Store()
self.parent = None
if(path.exists(self.dir)):
self.reload()
#self.pool.append(self) #register with pool
return(self)
#---------------------------------------------------------------------------
@property
def obs(self):
return(self._obs)
我發現一個討論beween的__init__
方法和Python's use of __new__ and __init__? 的__new__
方法根據收視率最高的評論,如果一個人繼承一個不可變的類型像str
一個只應使用新的, int
,unicode
或tuple
。但我認爲這是因爲其他原因。進一步,我不明白爲什麼類cls
應該有一個名字(以及爲什麼它應該有一些文件夾任何待辦事項),爲什麼我可以叫
n= Node()
n.obs
的功能等OBS將是一個性質的功能,但它其實不是..
我很困惑。如果你不是,我不能等待你的迴應。
謝謝你的回覆。 所以使用'__new__'的唯一原因是因爲有時候我想要一個已經被創建好的對象?這只是在'if(name!= None和cls._instances.has_key(name))'的情況下。我應該如何用name!= None調用'__new__'函數?我的意思是超時我創建了一個節點對象,我稱之爲'node = Node()',然後默認'name = None'。我還認爲cls是一個靜態的全局類對象。因此,如果我向全局類cls添加一個名稱,因爲每個對象都包含該名稱,因爲每個對象都是cls的子類 - 是否正確? – Adam 2013-05-03 17:18:58
@Adam:參見['__new__'](http://docs.python.org/2/reference/datamodel.html#object.__new__)文檔; 'cls'是對'__new__'方法傳入的類對象的引用(就像'self'傳入引用當前實例的方法一樣)。 Node()爲你創建一個新名字,如果你不通過('name = None'),理論上這個項目可以在需要的時候傳入一個明確的'name'。在這種情況下,'cls'會引用'Node'類或'Node'的任何子類。 – 2013-05-03 17:22:59
@Adam:Python類對象通常(在Python 3中,* always *),從'object'繼承,而不是'cls'。 'cls'只是這個方法的本地名稱。 – 2013-05-03 17:23:50