2016-09-16 55 views
0

我想添加一個屬性到我的方法使用裝飾器,以確定它是否已被調用。我無法弄清楚爲什麼我得到這個錯誤:TypeError:bet()缺少1個必需的位置參數:'betsize'。python將屬性添加到使用裝飾器的方法

文件game.py

class Game(object): 
    def __init__(self): 
     .. 

    @AddCalled 
    def bet(self, betsize): 
     print(betsize) 

文件addcalled.py:

class AddCalled(object): 
    def __init__(self, f): 
     self.f = f 
     self.called = False 

    def __call__(self, *args, **kwargs): 
     self.f(*args, **kwargs) 
     self.called = True 

我從一個Qt信號(點擊按鈕)的betsize。目標插槽功能BET()從game.py

文件mainui.py

class MainWindow(QtGui.QMainWindow, Ui_MainWindow): 
    .. 

    self.connect(self.ui.btnBet, SIGNAL("clicked()"), self.bet) 

    def bet(self): 
     #assuming 'game' is an instance of Game() 
     self.game.bet(self.ui.betLine.text()) 

現在,每當我對賭按鈕點擊

Traceback (most recent call last): 
    File "/home/njl/projet/mainui.py", line 27, in bet 
    self.game.bet(self.ui.betLine.text()) 
    File "/home/njl/projet/addcalled.py", line 15, in __call__ 
    self.f(*args, **kwargs) 
TypeError: bet() missing 1 required positional argument: 'betsize' 

我希望得到一些我得到這個錯誤幫幫我。 Litteraly卡在那裏。

+0

您的代碼有一個錯誤:您使用'self.f'將函數存儲在'__init__'中,但是您嘗試使用'call'中的'self.func'來訪問它。 – BrenBarn

+1

順便提一下,請注意,在方法被任何實例調用時,只將方法中的屬性存儲一次;它不會告訴你是否在'Game'的給定實例上調用了「bet」。這是否重要取決於你打算如何使用'被叫'屬性。 – BrenBarn

+0

哦,對不起,它實際上寫在我的代碼。我剛剛編輯它@BrenBarn – khanh

回答

2

你的裝飾器沒有正確地將self傳遞給包裝函數。

通常情況下,self由函數對象的描述符機制,將它們轉換上飛與self軋製方法添加的對象,但你有AddDecorator對象,不執行協議的描述符的替代方法,所以當你的AddDecorator包裝被調用時,它不知道它被調用的是什麼實例(即self應該是什麼)。

您可以通過給它一個__get__方法在AddDecorator類上實現描述符協議。或者你可以使用函數只寫一個普通的裝飾:

def addCalled(func): 
    def newFunc(*args, **kwargs): 
     newFunc.called = True 
     func(*args, **kwargs) 
    newFunc.called = False 
    return newFunc 
-1

當你寫:

@AddCalled 
def bet(self, betsize): 
    print(betsize) 

這相當於:

def bet(self, betsize): 
    print(betsize) 

bet = AddCalled(bet) 

所以,傳遞給AddCalled的說法是功能bet

+0

發生了什麼事?我讀了你的文章的一半,然後你刪除它:/ – khanh

+0

我刪除了結尾,因爲它是錯誤的 –

+0

@BrenBarn的解決方案是正確的。除了我更喜歡蛇情況函數名稱;-)。我也同意其關於如何舉報電話的評論。 –

相關問題