Python程序错误'list'对象不可调用

时间:2016-12-09 15:30:30

标签: python variables url lambda pyqt4

我已经按照本教程http://eli.thegreenplace.net/2011/04/25/passing-extra-arguments-to-pyqt-slot,目的是我在列表中有很多URL,我需要为我的下一个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__'

再次感谢您的任何输入。

3 个答案:

答案 0 :(得分: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

由于每个国家/地区的网址基本相同,我们可以从字典中构建它,这样可以更好地查找并轻松添加或更改。

现在,可以按以下方式定义按钮:

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

希望这是一种更易读的设置按钮的方法。

答案 1 :(得分:0)

如果将其更改为:

会发生什么
def get_country_url(self, n):

然后更改上面的所有lambdas以引用函数get_country_url(n)?

我认为问题是您已经给出了列表和功能相同的名称,因此当您希望它执行该功能时,它会尝试执行该列表....

我无法对此进行测试,因为我没有时间构建足够的代码来支持您提供的位。

答案 2 :(得分:0)

您正在使用列表覆盖函数country_url(self,...),方法是将其绑定到self.country_url。

只需将变量名称更改为self.country_urls = [...]或更改函数名称get_country_url(self,...)。