2013-03-05 33 views
0

我有一個類sysprops其中我想有一些常量。但是,我想從數據庫中獲取這些常量的值,所以在任何時候訪問這些類常量中的某一個時,我都會喜歡某種鉤子(類似於實例變量的getattribute方法)。是否有類似'__getattribute__'的類(非實例)變量?

class sysprops(object): 
    SOME_CONSTANT = 'SOME_VALUE' 

sysprops.SOME_CONSTANT # this statement would not return 'SOME_VALUE' but instead a dynamic value pulled from the database. 

回答

2

而其他兩個答案有一個有效的方法。我喜歡走「最不可思議」的路線。

你可以做類似於元類方法的東西,而不用實際使用它們。只需使用裝飾器。

def instancer(cls): 
    return cls() 

@instancer 
class SysProps(object): 
    def __getattribute__(self, key): 
     return key # dummy 

這將創建SysProps一個實例,然後分配給它回SysProps名。有效遮蔽實際的類定義並允許一個常量實例。

由於裝飾器在Python中更常見,我發現這種方式更容易理解其他需要閱讀代碼的人。

+0

應該指出,這使得不可能實例化'SysProps'類。而不是使用這種方法,我實際上會選擇只是簡單地執行'SysProps = SysProps()',而不是我看來更清楚:) – Wolph 2013-03-05 02:37:03

+0

您可能並不總是希望用戶實例化一個類 - 單例模式。 – Trevor 2013-03-11 22:51:32

0

sysprops.SOME_CONSTANT可以是如果SOME_CONSTANT被一個屬性上type(sysprops)定義的函數的返回值。

換句話說,如果sysprops是一個實例而不是一個類,那麼您通常會說什麼。

但是,這裏是踢球者 - 類是metaclass的實例。因此,通過使用類來控制實例行爲的一切知識同樣適用於通過使用元類來控制類的行爲。

元類通常是type,但您可以通過繼承type來自由定義其他元類。如果將屬性SOME_CONSTANT置於元類中,則該元類的實例(例如,當Python評估sysprops.SOME_CONSTANT時,sysprops將具有期望的行爲。


class MetaSysProps(type): 
    @property 
    def SOME_CONSTANT(cls): 
     return 'SOME_VALUE' 

class SysProps(object): 
    __metaclass__ = MetaSysProps 


print(SysProps.SOME_CONSTANT) 

產量

SOME_VALUE 
0

雖然我認爲這是一個非常壞主意要做到這一點,這是可能的:

class GetAttributeMetaClass(type): 
    def __getattribute__(self, key): 
     print 'Getting attribute', key 

class sysprops(object): 
    __metaclass__ = GetAttributeMetaClass