2010-05-15 57 views
0

我正在尋找一種方法來定義類似於C#的Python中的屬性,並帶有嵌套的get/set定義。
這是多遠我得到:python中的C#樣式屬性

#### definition ####  

def Prop(fcn): 
    f = fcn() 
    return property(f['get'], f['set']) 


#### test #### 

class Example(object): 

    @Prop 
    def myattr(): 

     def get(self): 
      return self._value 

     def set(self, value): 
      self._value = value 

     return locals() # <- how to get rid of this? 

e = Example() 
e.myattr = 'somevalue' 
print e.myattr 


這裏的問題是,它仍然需要定義爲「恢復當地人()」。
有沒有辦法擺脫它?
也許用嵌套裝飾器?

+2

也許我沒有得到什麼,但爲什麼是經典的'myattr = property(fget = get_value,fset = set_value)'還不夠? – Almad 2010-05-15 19:25:26

回答

2

你可以return get, set(一個更優雅的方式),讓你然而Prop

def Prop(fcn): 
    g, s = fcn() 
    return property(g, s) 

有不要求在裝飾功能的任何return聲明沒有乾淨方式。具有內部def語句的函數,就像具有內部賦值語句的函數一樣,實際上並沒有執行這些語句,直到它被調用 - 對象和名稱表示賦值和def s應該構建和綁定的字面上無處可見找到。

一旦叫,說的名字和對象是局部的作用 - 所以,他們離開,除非他們的外部引用存在......和真的沒有更優雅的方式,以保證當地這樣的外部引用除了return以某種形式存在的名字。

問題來自於堅持要裝飾一個函數對象(通過設計,它的本地名稱非常貼近自身)。如果您同意使用正確的關鍵字而不是def作爲裝飾物 - 那麼正確的關鍵字是class,那麼一切都會很好,很花哨。 (請注意,你需要的Python 2.6或用於此目的的更好)...:

def Prop(cls): 
    f = cls.__dict__ 
    return property(f['get'], f['set']) 


#### test #### 

class Example(object): 

    @Prop 
    class myattr(): 

     def get(self): 
      print 'getting', self._value 
      return self._value 

     def set(self, value): 
      print 'setting', value 
      self._value = value 


e = Example() 
e.myattr = 'somevalue' 
print e.myattr 

類是比功能WRT詭祕得多什麼是「裏面」出來的,所以裝飾可以輕鬆地完成你」重新過後。請注意微小的更改:__dict__可以訪問正在裝飾的類的字典,s/def/class/正在裝飾的對象,並刪除您不喜歡的return語句。

+0

感謝您提供詳細的解釋。類裝飾器刪除'返回locals()',但增加了一個內部類,這對我來說也是'感覺錯誤'。 (整個事情只是關於語法口味的問題)。之後使用反射無法以某種方式粘貼「返回本地()」? – 3dGrabber 2010-05-15 19:57:31

+1

@ 3D-Grabber,「內部類」會消失,因爲裝飾器只是使用它而不返回它。是的,你**可以通過字節碼反彙編和內省使**錯誤**關鍵字('def')的行爲_almost_以及** right **關鍵字在這種情況下變得瘋狂('class' )自然地,無縫地,毫不費力地 - 但是,我已經完成了我的字節碼黑客份額,然後一些,我現在拒絕成爲這種自我破壞性努力的推動者;-)。超過50行錯綜複雜,脆弱細膩的代碼,當你真的意味着'class'但是'不喜歡它'時,讓你說'def'。拒絕吧!-) – 2010-05-15 20:30:45