2016-12-09 35 views
0

我按照本教程http://eli.thegreenplace.net/2011/04/25/passing-extra-arguments-to-pyqt-slot,目標是我有一大堆的URL在列表中,我需要返回一個爲我的下一個Python類,以便我可以刮來自該頁面的統計信息。我安裝我的代碼昨晚並確保它的工作沒有任何麻煩,但是當我今天早上回來吧我收到以下內容:Python程序錯誤「列表」對象不可調用

/usr/bin/python2.7 /home/student/Project/country_selection.py 
Traceback (most recent call last): 
    File "/home/student/Project/country_selection.py", line 39, in <lambda> 
    self.ui.irelandButton.clicked.connect(lambda: self.country_url(11)) 
TypeError: 'list' object is not callable 

Process finished with exit code 0 

這是我使用的這個項目我將大大代碼欣賞可用的輸入。

import sys 
from PyQt4 import QtCore, QtGui 
from country_selection_ui import Ui_CricketStats 

class CountryPlayer(QtGui.QMainWindow): 
    """ 
    This program is used to return the url required for the player selection program 
    each button on the GUI represents a different country and is defined so that when 
    it is clicked it will pass a variable to the country_url method which in turn 
    will then use the variable to return a url. 
    """ 
    def __init__(self, parent=None): 
     """ 
     In this method I have used the lambda function so that I can push the variable 
     required in the country_url. Lambda is a built in tool in Python and is there 
     for building functions. I once asked Darren Dowdall to explain what lambda was 
     and his explanation seems to fit best with me "It is a throw away function". We 
     use lambda function once then it is gone unlike def function which can be used 
     over and over again. 
     :param parent: 
     """ 

     QtGui.QWidget.__init__(self, parent) 
     self.ui = Ui_CricketStats() 
     self.ui.setupUi(self) 

     # what the button does when pushed 
     self.ui.australiaButton.clicked.connect(lambda: self.country_url(0)) 
     self.ui.indiaButton.clicked.connect(lambda: self.country_url(1)) 
     self.ui.englandButton.clicked.connect(lambda: self.country_url(2)) 
     self.ui.pakistanButton.clicked.connect(lambda: self.country_url(3)) 
     self.ui.southafricaButton.clicked.connect(lambda: self.country_url(4)) 
     self.ui.newzealandButton.clicked.connect(lambda: self.country_url(5)) 
     self.ui.srilankaButton.clicked.connect(lambda: self.country_url(6)) 
     self.ui.westindiesButton.clicked.connect(lambda: self.country_url(7)) 
     self.ui.zimbabweButton.clicked.connect(lambda: self.country_url(8)) 
     self.ui.bangladeshButton.clicked.connect(lambda: self.country_url(9)) 
     self.ui.kenyaButton.clicked.connect(lambda: self.country_url(10)) 
     self.ui.irelandButton.clicked.connect(lambda: self.country_url(11)) 
     self.ui.canadaButton.clicked.connect(lambda: self.country_url(12)) 
     self.ui.netherlandsButton.clicked.connect(lambda: self.country_url(13)) 
     self.ui.scotlandButton.clicked.connect(lambda: self.country_url(14)) 
     self.ui.afghanistanButton.clicked.connect(lambda: self.country_url(15)) 
     self.ui.usaButton.clicked.connect(lambda: self.country_url(16)) 

    def country_url(self, n): 
     """ 
     This method is used to return the url required for the player selection program. 

     :param n: is the number which is directly related to the country url position in the 
        self.country_url list. 
     :return: 
     """ 
     self.country_url = ["http://www.espncricinfo.com/australia/content/player/country.html?country=2", 
          "http://www.espncricinfo.com/india/content/player/country.html?country=6", 
          "http://www.espncricinfo.com/england/content/player/country.html?country=1", 
          "http://www.espncricinfo.com/pakistan/content/player/country.html?country=7", 
          "http://www.espncricinfo.com/southafrica/content/player/country.html?country=3", 
          "http://www.espncricinfo.com/newzealand/content/player/country.html?country=5", 
          "http://www.espncricinfo.com/srilanka/content/player/country.html?country=8", 
          "http://www.espncricinfo.com/westindies/content/player/country.html?country=4", 
          "http://www.espncricinfo.com/zimbabwe/content/player/country.html?country=9", 
          "http://www.espncricinfo.com/bangladesh/content/player/country.html?country=25", 
          "http://www.espncricinfo.com/kenya/content/player/country.html?country=26", 
          "http://www.espncricinfo.com/ireland/content/player/country.html?country=29", 
          "http://www.espncricinfo.com/canada/content/player/country.html?country=17", 
          "http://www.espncricinfo.com/netherlands/content/player/country.html?country=15", 
          "http://www.espncricinfo.com/scotland/content/player/country.html?country=30", 
          "http://www.espncricinfo.com/afghanistan/content/player/country.html?country=40", 
          "http://www.espncricinfo.com/usa/content/player/country.html?country=11"] 
     return self.country_url[n] 

if __name__ == '__main__': 


    app = QtGui.QApplication(sys.argv) 
    myapp = CountryPlayer() 
    myapp.show() 
    sys.exit(app.exec_()) 

在情況下,我也忍了其與PyQt4的在以下鏈接使我的GUI代碼:https://paste.ee/p/OwAcw,因爲我在這一點上完全喪失。我不知道爲什麼它拋出錯誤'list'對象不可調用。我還將括號更改爲[],但出現以下錯誤:

/usr/bin/python2.7 /home/student/Project/country_selection.py 
Traceback (most recent call last): 
    File "/home/student/Project/country_selection.py", line 39, in <lambda> 
    self.ui.irelandButton.clicked.connect(lambda: self.country_url[11]) 
TypeError: 'instancemethod' object has no attribute '__getitem__' 

再次感謝您的任何輸入。

+1

您似乎使用'country_url'作爲方法名稱'def country_url(self,n)'和一個屬性''self.country_url = ...',這可能會導致衝突。 – asongtoruin

回答

1

我不能完全測試這個,所以如果有任何的錯誤,我很抱歉。這希望能起作用,但可能不是最佳實踐。

你的問題來自使用方法和屬性country_url - 這會導致衝突,並且是你想避免的。

我們可以通過更改country_url方法來使代碼更具可讀性並希望避免此類衝突。讓我們改變這一點,它重命名爲get_url(因爲這是該方法的一個更合乎邏輯的名稱),如下所示:

def get_url(self, country_name): 
    """ 
    This method is used to return the url required for the player selection program. 

    :param country_name: is the name of the country. 
    :return: 
    """ 

    country_dict = {'australia': '2', 
        'india': '6', 
        'england': '1', 
        'pakistan': '7', 
        'southafrica': '3', 
        'newzealand': '5', 
        'srilanka': '8', 
        'westindies': '4', 
        'zimbabwe': '9', 
        'bangladesh': '25', 
        'kenya': '26', 
        'ireland': '29', 
        'canada': '17', 
        'netherlands': '15', 
        'scotland': '30', 
        'afghanistan': '40', 
        'usa': '11'} 

    if country_name in country_dict.keys(): 
     return "http://www.espncricinfo.com/{0}/content/player/country.html?country={1}"\ 
      .format(country_name, country_dict[country_name]) 
    else: 
     raise ValueError 

由於URL每個國家基本上是相同的,我們可以從一本字典,構建它這使其更容易找到並易於添加或更改。

現在,按鈕可以以如下方式來定義:

self.ui.australiaButton.clicked.connect(lambda: self.get_url('australia')) 

哪個是,希望設置按鈕向上的更可讀的方式。

+0

感謝一百萬人的魅力仍然不知道爲什麼它今天晚上的經文。我重寫了原來的代碼,它找到了,但是一旦我關閉了系統並重新打開它,我又得到了錯誤。另一方面,您的代碼完美地工作,再次感謝。 –

+0

非常歡迎您 - 謹慎使用名稱並儘量避免可能的衝突。 – asongtoruin

0

會發生什麼,如果你將其更改爲:

def get_country_url(self, n): 

,然後改變所有的lambda表達式以上引用的函數get_country_url(N)?

我認爲這個問題是你給的列表和功能相同的名稱,所以它的嘗試,當你希望它執行的函數來執行列表....

我無法測試這一點,因爲我沒有時間來構建足夠的代碼來支持你提供的位。

0

您正在用列表將覆蓋函數country_url(self,...),方法是將其指定爲self.country_url。

只需將變量名稱更改爲self.country_urls = [...]或更改函數名稱get_country_url(self,...)。

相關問題