Python“泛型”类属性编码/解码

时间:2011-04-26 13:35:00

标签: python

我几乎可以保证这很简单。我正在尝试创建一个通用属性来包装django text / blob字段。这不是Django特有的,它实际上只是一个设计问题。我有一些类级变量,并使用伪委托,以便能够重用解码方法。

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)

3 个答案:

答案 0 :(得分:3)

只需从self删除get_data,然后将其设为课堂外的功能。

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

答案 1 :(得分:1)

使用def get_data(prop): - 只有你的内部函数应该接受self,因为外部函数不作为实例方法执行。

答案 2 :(得分:0)

你可以用lambda:

做到这一点
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'))