2016-08-01 36 views
1

我有一个类,用于将二进制流转换为人类可读的类。我想翻译它,因为我发送和接收二进制消息。这个类的属性大部分都是相同的 - 从startbyte到stopbyte的字节并解码它们 - 所以我决定使用一个属性来做到这一点。但是,我可以在定义我的类属性时制作一般的“属性”吗?在Python中为类属性创建'标准属性'

class Packet(object): 
    def __init__(self, data): 
     self.data = data 

    def standard_getter(startbyte, stopbyte): 
     def getter(self): 
      return decode(self.data[startbyte:stopbyte]) 
     return getter 

    def standard_setter(startbyte, stopbyte): 
     def setter(self, value): 
      self.data[startbyte:stopbyte] = encode(value) 
    return setter 

    # the way I define properties by now: 
    protocol_type = property(standard_getter(16, 18), standard_setter(16, 18)) 
    protocol_sub_type = property(standard_getter(18, 20), standard_setter(18, 20)) 

    # the way I would like to do it: 
    protocol_type = property(standard_property(16, 18)) 
    # or 
    protocol_type = standard_property(16, 18) 

我试图定义一个函数,有两个参数,并返回财产(的getter,setter方法),但始终我被困在给“自我”实例的功能。有一种很好的方式可以做到吗?

回答

3

让你的函数产生getter和setter都,并返回这两个函数的property对象:

def standard_property(startbyte, stopbyte): 
    def getter(self): 
     return decode(self.data[startbyte:stopbyte]) 
    def setter(self, value): 
     self.data[startbyte:stopbyte] = encode(value) 
    return property(getter, setter) 

然后直接使用的返回值:

protocol_type = standard_property(16, 18) 
protocol_sub_type = standard_property(18, 20) 

注意,standard_property()功能甚至不需要住在你的班上;它也可能是一个顶级功能:

>>> def standard_property(startbyte, stopbyte): 
...  def getter(self): 
...   return decode(self.data[startbyte:stopbyte]) 
...  def setter(self, value): 
...   self.data[startbyte:stopbyte] = encode(value) 
...  return property(getter, setter) 
... 
>>> encode = lambda v: list(v) 
>>> decode = lambda v: ''.join(v) 
>>> class Packet(object): 
...  def __init__(self, data): 
...   self.data = data 
...  protocol_type = standard_property(16, 18) 
...  protocol_sub_type = standard_property(18, 20) 
... 
>>> p = Packet(list('foo bar baz spam ham eggs')) 
>>> p.protocol_type 
' h' 
>>> p.protocol_sub_type 
'am' 
>>> p.protocol_type = '_c' 
>>> p.protocol_sub_type = 'an' 
>>> ''.join(p.data) 
'foo bar baz spam_can eggs' 
+0

伟大的,这就是我所需要的。我知道我可以把它放在课外,但现在对我来说没有意义。 – Grysik