2014-03-04 38 views
0

我想在一個類中使用屬​​性和裝飾器,但我一直運行的問題是獲取正確的參數和參數的數量。使用類內部屬性的Python裝飾器

class Xml(object): 
    def __init__(self, data_dictionary=None): 
     self.data_dictionary = data_dictionary 

    def xml_wrapper(xml_msg): 
     def wrap(): 
      return '<?xml version="1.0" encoding="UTF-8"?>\n'+xml_msg['name'] 
     return wrap 


    @property 
    @xml_wrapper 
    def data_dictionary(self): 
     return self._data_dictionary 

    @data_dictionary.setter 
    def data_dictionary(self, data): 
     self._data_dictionary = data 


if __name__ == '__main__': 
    xml = Xml() 
    xml.data_dictionary = {'name': 'name 1'} 
    print xml.data_dictionary 

我得到的錯誤是

print xml.data_dictionary 
TypeError: wrap() takes no arguments (1 given) 

我不知道爲什麼,我嘗試添加自己的xml_wrapper功能,但我仍然得到一個錯誤。

+0

'data_dictionary'正在被'xml_wrapper'裝飾器封裝,它返回一個不帶任何參數的函數('wrap');但是當你調用'xml.data_dictionary'時,隱式參數'xml'('self')正在被傳遞。 – mshsayem

回答

1

在您的代碼中,xml_wrapper是一個裝飾器,它接受一個函數,然後用另一個函數(wrap)包裝並返回它。函數wrap不帶任何參數(如在您的代碼中)。但是當你調用xml.data_dictionary時,python隱式地傳遞了導致問題的實例xml(稱爲self)。可能這是你想要什麼:

>>> class Xml(object): 
     def __init__(self, data_dictionary=None): 
      self.data_dictionary = data_dictionary 

     def xml_wrapper(f): 
      def wrap(*k,**kw): 
       xml_msg = f(*k,**kw) 
       return '<?xml version="1.0" encoding="UTF-8"?>\n'+xml_msg['name'] 
      return wrap 


     @property 
     @xml_wrapper 
     def data_dictionary(self): 
      return self._data_dictionary 

     @data_dictionary.setter 
     def data_dictionary(self, data): 
      self._data_dictionary = data 


>>> xml = Xml() 
>>> xml.data_dictionary = {"name":"name 1"} 
>>> print xml.data_dictionary 
<?xml version="1.0" encoding="UTF-8"?> 
name 1 

這次xml_wrapper走的是一條函數(data_dictionary),然後調用這個函數來獲取xml_msg(內wrap)。 wrap現在需要任意多個參數,並將這些參數傳遞給原始函數(data_dictionary),取值,格式化並返回。

+0

既然xml_wrapper不是類的一部分(意思是它沒有自我作爲第一個參數),我應該把它放在類中還是作爲一個獨立的函數?什麼是pythonic的方式來做到這一點? –

+0

我認爲這是一個偏好問題。由於裝飾器與'self'無關,實際上它可以放在另一個模塊中。但是,當類正在處理Xml時,將該裝飾器放入類中也是有意義的。我更喜歡後者。 – mshsayem