2013-08-22 26 views
0

這裏是從學習Python中提取和改編的代碼,在第5行中lambda的用法是什麼,看起來print(X.__str__())期望0個參數,是*args在這裏是不必要的?這個python代碼中lambda的用法是什麼?

class GetAttr: 
    def __getattr__(self, attr): 
     print('getattr: ' + attr) 
     if attr == '__str__': 
      return lambda *args: '[Getattr str]' 
     else: 
      return lambda *args: None 

X = GetAttr() 
print(X.__call__('why', 'any', 'number', 'of', 'arguments', 'here')) 
print(X.__str__()) # but not here? 

回答

2

attr == '__str__',函數需要返回一個可調用對象,因爲__str__預計的方法。簡單地返回一個字符串會給你一個錯誤,抱怨'str'對象不可調用。

但是,*args不是必需的,因爲__str__永遠不會被調用任何參數。這足以:

return lambda: '[Getattr str]' 

請注意,如果您使用python2和建議從object繼承,示例不起作用。如果你使用python3,它也不起作用。這是在這些情況下的輸出:

 
getattr: __call__ 
None 
<__main__.GetAttr object at 0xb728ff6c> 

爲什麼不__getattr__調用時attr == '__str__'

這是因爲基類object已經實現了一個默認的__str__方法,而我們的__getattr__功能僅要求失蹤屬性。爲了修正這個例子,我們必須使用__getattribute__方法,但是使用beware of the dangers

class GetAttr(object): 
    def __getattribute__(self, attr): 
     print('getattr: ' + attr) 
     if attr == '__str__': 
      return lambda: '[Getattr str]' 
     else: 
      return lambda *args: None 

更好和更可讀的解決方案是簡單地明確地重寫__str__方法。

class GetAttr(object): 
    def __getattr__(self, attr): 
     print('getattr: ' + attr) 
     return lambda *args: None 

    def __str__(self): 
     return '[Getattr str]' 

雖然python比較好,但是這個例子的大部分內容都丟失了。

0

它用於粉碎交給它的任何參數。無論您輸入多少參數__str__(),它都會基本忽略它們。

另一方面,這是非常可怕的Python編寫的。你可能想嘗試其他的東西

0

lambda使函數返回一個函數。

0

是的,在這種情況下是不必要的,因爲X.__str__()總是會被調用而沒有參數。這取決於你想要什麼樣的行爲,當它被錯誤地稱爲與ARGS:

str1 = lambda *args: "[Getattr str]" 
str2 = lambda : "[Getattr str]" 

str1(1,2,3) #works, args ignored 
str2(1,2,3) #throws runtime error