【问题标题】:Issue calling method outside class python在类python之外发出调用方法
【发布时间】:2017-01-11 23:24:44
【问题描述】:

我正在研究一个涉及创建和使用具有多种方法的类的 python 评估。我不会发布整个内容,因为如果我展示我正在尝试做的事情的示例,那么指出我的问题会更简单。

class Fruit(self,color,name):
    def __init__(self, color, name):
        self.color = color
        self.name = name

    def return_list(self, index):
        print fruit_list[index]

fruit_list = []

fruit_1 = Fruit("red", "apple")
fruit_list.append(fruit_1.color) 
fruit_list.append(fruit_1.name)

所以上面的代码有效。我的问题是让 return_list 在课堂外使用时起作用,如下所示:

fruit_choice = int(raw_input("What fruit would you like?"))
Fruit.return_list(fruit_choice)

基本上我正在尝试创建一个方法,当被调用时,在列表中的索引处输出项目,该索引由用户输入指定(即fruit_choice = 0,打印的项目是列表的第一个元素。)

我对类有基本的了解,但是像 return_list 这样有点模糊的方法有点不直观。我得到的错误信息:

Fruit.return_list(fruit_choice)
TypeError: unbound method return_list() must be called with Fruit instance as first argument (got int instance instead)

我知道如果我让代码工作,如果输入为 0 而不是“red,”apple,则输出将是“red”,但这是另一个问题。

如果有人能指出我在创建/调用 return_list 方法时做错了什么,请感谢。

【问题讨论】:

  • Fruit.return_list(fruit_choice) 应该是 fruit_1.return_list(fruit_choice)。您必须将该方法附加到一个实例(这就是消息所说的)。但在那之后它就不起作用了,因为fruit_list 不是该类的成员(这不应该是因为您不希望水果对象中有水果列表!)。多学习 OO 编程...

标签: python list python-2.7 class methods


【解决方案1】:

基本上你是在调用一个没有实例的实例方法,这就是你得到这个错误的原因

    TypeError: unbound method return_list() must be called with Fruit instance as first argument (got int instance instead)

修改后的代码

    fruit_1.return_list(fruit_choice)

您正在做的方式是静态方法的行为,它们在没有实例的情况下被调用。 请通过python中的实例方法和静态方法等一些oops编程。

希望对你有帮助:)

【讨论】:

    【解决方案2】:

    您似乎对类和类实例有误解。

    您定义的return_list 函数是Fruit 类的一部分,即Fruit 类的每个实例都包含此方法。但是这个函数的使用,即从水果列表中返回一个特定的水果,是独立于单个 Fruit 实例的,这意味着这个方法本来就不应该在 Fruit 类中。

    类定义class Fruit(self,color,name)的签名错误。应该是class Fruit:。初始参数应定义为__init__ 方法的参数。

    列表fruit_list 应包含Fruit 实例。程序可以写成:

    class Fruit:
        def __init__(self, color, name):
            self.color = color
            self.name = name
    
        def __str__(self):
            return 'I am a ' + self.color + ' ' + self.name
    
    fruit_list = []
    
    fruit_1 = Fruit("red", "apple")
    fruit_list.append(fruit_1)
    
    fruit_choice = int(raw_input("What fruit would you like?"))
    print(fruit_list[fruit_choice])
    

    打印 Python 对象调用 __str__ 魔术方法。

    如果你真的想要一个从fruit_list返回Fruit的单独函数,你可以在类之外定义一个函数(但是当你可以使用索引直接访问实例时,这些似乎是不必要的):

    def return_list(list, index):
        return list[index]
    

    def return_list(index):
        global fruit_list
        return fruit_list[index]
    

    如果您尝试使用print(fruit_list) 打印整个列表,则输出为:

    [<__main__.Fruit instance at 0x110091cf8>]
    

    这是因为当您打印实例列表时,Python 不会在每个实例上调用 __str__。您可以通过以下方式打印fruit_list

    for fruit in fruit_list:
        print(fruit)
    

    【讨论】:

    • 谢谢,这对我帮助很大。如果我想显示整个列表,我会怎么做?只是将 [:] 作为索引或根本没有 [] 似乎不起作用。(参考您的第一个代码块)
    【解决方案3】:

    以下是解决您问题的可能方法:

    class Fruit():
    
        def __init__(self, color, name):
            self.color = color
            self.name = name
    
        def __str__(self):
            return "Color: {0} Name: {1}".format(self.color, self.name)
    
    
    class FruitBasket():
    
        def __init__(self):
            self.fruits = []
    
        def get_fruit(self, index):
            try:
                value = self.fruits[index]
                return value
            except Exception as e:
                print "Error with index {0} -> {1}".format(index, e)
    
    if __name__ == "__main__":
        basket = FruitBasket()
        names = ["apple", "orange", "lemon"]
        colors = ["green", "orange", "yellow"]
    
        for name, color in zip(names, colors):
            fruit = Fruit(color, name)
            basket.fruits.append(fruit)
    
        print basket.get_fruit(0)
        print basket.get_fruit(1)
        print basket.get_fruit(2)
        basket.get_fruit(3)
    

    关于上面代码的几个cmet:

    • 水果对象没有比设置具有特定名称和颜色的水果更多的责任,这差不多。一个水果不应该包含任何水果列表,这应该是另一个对象的责任
    • FruitBasket 是水果的容器,您可以在不使用 OOP 的情况下完美地做到这一点,但就这个问题而言,这是容纳许多水果的有效选项

    关于您的错误,其他答案和 cmets 已经指出了问题所在。另外,关于class Fruit(self,color,name):,不要那样做,在这句话中你声明的是类类型,而不是构造函数。

    我强烈建议您尝试关注其中的许多OOP python tutorials

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-07
      • 2015-11-22
      • 2021-06-11
      • 1970-01-01
      • 2016-09-02
      • 2013-09-28
      相关资源
      最近更新 更多