Python“;“通用”;类属性编码/解码

Python“;“通用”;类属性编码/解码,python,Python,我几乎可以保证这很简单。我试图创建一个通用属性来包装django文本/blob字段。这不是Django特有的,它实际上只是一个设计问题。我有一些类级变量,正在使用伪委托来重用解码方法 class DBTable(models.Model): class Meta: db_table="some_table" def set_data(self, data): att = self.__getattribute__(data.__name__) att =

我几乎可以保证这很简单。我试图创建一个通用属性来包装django文本/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)
问题就在上面两行,我需要通过self。我尝试过使用这个类,但它没有被识别


这很简单,上面的问题通过拔出解决了,下面是最终的工作解决方案

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)

只需从
get_data
中删除
self
,并使其成为类外的函数

get\u data\u factory(“blob\u a”)
将返回一个函数,该函数需要
self
作为参数。那很好。它不必从
get\u 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\u data
decode\u 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

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

您可以使用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'))

我是否只需要忽略关于需要将self作为第一个参数的“警告”?除了“忽略”之外,还有没有一个不那么难闻的注释?@Nix:你能出示警告吗?我不知道你为什么要得到一个。我收到了警告bc我把get_数据留在了类中。@尼克斯:我认为不可能在类定义中定义它,因为在类定义完成之前你不能调用方法、staticmethods或classmethods。您必须将
get\u data\u factory
移到类定义之外,或者将
blob\u a=property(…)
语句移到类定义之外。从技术上讲,您可以将其保留在类定义中,它仍然可以工作。;)它只是一堆糟糕的代码,在ide中很难看,我将其升级,并将其命名为encode/decode,使其更通用。谢谢您的帮助。在您的最终解决方案中,
get_data
set_data
是如何定义的?我有一个输入错误,我将它们重命名为encode/decode。然而它还不是最终的,因为我在一个无限循环中,它基本上递归地调用setattr。现在正在努力。