2011-04-26 91 views
2

我幾乎保證這是簡單的。我正在嘗試創建一個通用屬性來包裝Django文本/ blob字段。這不是Django特有的,它只是一個設計問題。我有一些類級別的變量,並使用僞代理來重用解碼方法。Python「通用」類屬性編碼/解碼

class DBTable(models.Model): 
    class Meta: 
    db_table="some_table" 

    def set_data(self, data): 
    att = self.__getattribute__(data.__name__) 
    att = base64.encodestring(data) 

    def get_data(self,prop): 
    def func(self): 
     att = self.__getattribute__(prop) 
     return base64.decodestring(att) 
    return func 

    #issue is here, i need to pass self to get_data 
    blob_a = property(get_data("blob_a"), set_data) 
    blob_b = property(get_data('blob_b'), set_data) 

而且問題涉及上述兩行,我需要通過自我。我曾嘗試過使用該課程,但無法識別。


很簡單,上面的問題通過拔出來解決,下面是最終的工作解決方案。

def encode_data(self, data): 
    def func(self,data): 
     self.__setattr__(prop, base64.encodestring(data)) 
    return func 

def decode_data(self,prop): 
    def func(self): 
     att = self.__getattribute__(prop) 
     return base64.decodestring(att) 
    return func 


class DBTable(models.Model): 
    class Meta: 
    db_table="some_table" 

    blob_a = property(decode_data("_blob_a"), encode_data("_blob_a")) 
    blob_b = property(decode_data('_blob_b'), encode_data("_blob_b")) 

    _blob_a = models.TextField(
     db_column='blob_a', 
     blank=True) 
    _blob_b = models.TextField(
     db_column='blob_b', 
     blank=True) 
+0

在你的最終解決方案,是如何'get_data'和'set_data'界定? – unutbu 2011-04-26 14:10:28

+0

我有一個錯字,我將它們重命名爲編碼/解碼。然而,它不是最終的但BC我處於一個無限循環,它基本上遞歸調用setattr。現在就開始工作。 – Nix 2011-04-26 14:14:44

回答

3

只需從get_data刪除self,使之類之外的功能。

get_data_factory("blob_a")將返回一個函數,該函數需要self作爲參數。這很好。它不必從get_data收到(實際上它不應該收到)該值。

def get_data_factory(prop): 
    def get_data(self): 
     return base64.decodestring(getattr(self,prop)) 
    return get_data 

class DBTable(models.Model): 
    ... 
    blob_a = property(get_data_factory("blob_a"), set_data) 

關於最終的解決方案:我認爲有與encode_datadecode_data呼叫簽名有問題。也許你的意思是:

def encode_data(prop): 
    def func(self,data): 
     setattr(self,prop, base64.encodestring(data)) 
    return func 

def decode_data(prop): 
    def func(self): 
     return base64.decodestring(getattr(self,prop)) 
    return func 
+0

我是否需要忽略關於需要自我作爲第一個參數的「警告」?除了忽略之外,有沒有更少的臭味annoation? – Nix 2011-04-26 13:47:26

+0

@Nix:你能顯示警告嗎?我不知道爲什麼你應該得到一個。 – unutbu 2011-04-26 13:51:41

+0

我有警告bc我離開班級裏的get_data。 – Nix 2011-04-26 13:53:00

1

使用def get_data(prop): - 作爲外一個沒有作爲一個實例方法只執行你的內部函數應該接受self

0

你可以使用拉姆達做到這一點:

blob_a = property(lambda s: s.get_data('blob_a'), lambda s: s.set_data('blob_a')) 
blob_b = property(lambda s: s.get_data('blob_b'), lambda s: s.set_data('blob_b'))