Python "generic" class property encode/decode
I almost guarantee this is something simple. I am trying to create a generic property to wrap a django text/blob field. This isn't Django specific, its really just an issue with design. I have some class level variables and am using a pseudo delegate to be able to reuse an decode method.
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.__开发者_JAVA技巧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)
And the issue comes on the above two lines, I need to pass self. I have tried using the class but its not recognized.
It was simple, the problem above was fixed by pulling it out, and below is the final working solution.
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)
Simply remove self
from get_data
and make it a function outside the class.
get_data_factory("blob_a")
will return a function, which expects self
as an argument. That is perfectly fine. It does not have to receive (in fact, it should not receive) that value from 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)
Regarding the final solution: I think there is a problem with the call signature of encode_data
and decode_data
. Perhaps you meant:
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
Use def get_data(prop):
- only your inner function should accept self
as the outer one is not executed as an instance method.
You could do this with 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'))
精彩评论