2010-07-23 64 views
1

在Python中,我想要一個具有初始化值的類屬性,一個字典。我寫了這個代碼:Python - 從類內部引用類名稱

class MetaDataElement: 
    (MD_INVALID, MD_CATEGORY, MD_TAG) = range(3) 
    mapInitiator2Type = {'!':MetaDataElement.MD_CATEGORY, 
         '#':MetaDataElement.MD_TAG} 

但是當我嘗試運行這段代碼,我得到一個錯誤消息「NameError:名字‘MetaDataElement’沒有定義」。你可以幫幫我嗎?

在此先感謝。

回答

2

正在建設中,而它不能指MetaDataElement,因爲它還不存在。因此,

class MetaDataElement: 
    (MD_INVALID, MD_CATEGORY, MD_TAG) = range(3) 
    mapInitiator2Type = {'!':MetaDataElement.MD_CATEGORY, 
         '#':MetaDataElement.MD_TAG} 

失敗的原因爲mapInitiator2Type非常需要建設到MetaDataElement有屬性,它還不具備。你可以把你的常量MD_INVALID等看作是你的類的本地構造的變量。這就是爲什麼下面的作品,icktoofay寫道:

class MetaDataElement: 
    (MD_INVALID, MD_CATEGORY, MD_TAG) = range(3) 
    mapInitiator2Type = {'!': MD_CATEGORY, # MD_CATEGORY is like a local variable! 
         '#': MD_TAG} 

但是,您可以參考類MetaDataElement任何尚未未解釋的代碼,如

def method_of_MetaDataElement(self): 
     print MetaDataElement.MD_TAG 

你甚至參考MetaDataElement,在這裏,因爲當執行method_of_MetaDataElement()MD_TAG不是一種局部變量(MD_TAG僅在類構造期間被定義爲一種局部變量)。一旦類MetaDataElement創建,MD_TAG只是一個類屬性,這就是爲什麼method_of_MetaDataElement()必須這樣。

+0

最後一個例子可以用'self.MD_TAG'編寫,它避免了引用類的任何需要名稱。 – Marcin 2012-07-13 03:43:38

+0

@Marcin:'self.MD_TAG'也是一種可能性,但它不等同於'MetaDataElement.MD_TAG',如果MetaDataElement被子類化(子類可能會覆蓋'MD_TAG')。兩者都是有效的,但哪一個選擇取決於當前的情況。 – EOL 2012-07-13 07:48:33

+0

老實說,我認爲防止子類能夠有效地改變類成員的方法可能是錯誤的,這就是爲什麼我會推薦使用'self',除非有特定的理由來阻止它。 – Marcin 2012-07-13 13:14:05

0

首先,您使用的是舊式類。您應該使用新式類,如下所示:

class MetaDataElement(object): 
    ... 

請注意(object)。無論如何,只要在引用類屬性時刪除MetaDataElement.即可。這是它會是什麼時候這樣做了,如:

class MetaDataElement(object): 
    (MD_INVALID, MD_CATEGORY, MD_TAG) = range(3) 
    mapInitiator2Type = {'!': MD_CATEGORY, 
         '#': MD_TAG} 
+0

也許redism是在Python 3中編寫的,*是*使用新風格的類。 :) – EOL 2010-07-23 06:40:32

+0

@EOL:我沒有意識到Python 3默認使用了新風格的類。這很好。 – icktoofay 2010-07-24 02:23:27

+0

以下是參考資料:「經典課不見了。」 (http://docs.python.org/release/3.0.1/whatsnew/3.0.html#removed-syntax) – EOL 2010-07-24 10:30:44