2009-08-03 51 views
5

創建屬性我有這樣的事情:使用lambda getter和setter

class X(): 
    def __init__(self): 
     self.__name = None 

    def _process_value(self, value): 
     # do something 
     pass 

    def get_name(self): 
     return self.__name 

    def set_name(self, value): 
     self.__name = self._process_value(value) 

    name = property(get_name, set_name) 

可以用lambda函數代替我和get_nameset_name

我已經試過這樣:

name = property(lambda self: self.__name, lambda self, value: self.__name = self.process_value(value)) 

但是編譯器不喜歡我的setter函數。

+0

什麼是 「水木清華」? – 2009-08-04 01:18:01

+0

可能是'某事'。 – hughdbrown 2009-08-04 03:06:37

回答

19

你的問題是lambda的body必須是一個表達式並且賦值是一個語句(在Python中是一個強大而深刻的區別)。如果硬要犯下lambda是你能滿足很多這樣的情況,學會變通方法(通常有一個,但並不總是),例如,在這種情況下:

name = property(lambda self: self.__name, 
       lambda self, value: setattr(self, 
              '_X__name', 
              self.process_value(value))) 

即使用內置setattr(這是一種功能,因此在lambda的身體中是可以接受的),而不是分配(這是一種陳述,因此在lambda的身體中是不可接受的)。

編輯:您還需要進行名稱重整手動雙下劃線屬性(改變__name_X__name,你在課堂X是),其中屬性名是作爲一個引用的字符串,因爲它必須在setattr中,因爲Pyhon編譯器只會爲合適的標識符修改名稱,而不是字符串文字。

1

如果要擴展一個list,你也可以使用__setitem__,像這樣:

class Position(list): 
    def __init__(self,x=0, y=0, z=0): 
     super(Position, self).__init__((x,y,z)) 

    x = property(lambda self: self[0], 
       lambda self,value: self.__setitem__(0, value)) 
    y = property(lambda self: self[1], 
       lambda self,value: self.__setitem__(1, value)) 
    z = property(lambda self: self[2], 
       lambda self,value: self.__setitem__(2, value))