2016-08-01 60 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