提问人:Ryan R. McKnight 提问时间:8/4/2023 最后编辑:Scott HunterRyan R. McKnight 更新时间:8/4/2023 访问量:32
为什么我在第二次运行类方法时收到 TypeError?
Why am I getting a TypeError the second time I run a class method?
问:
Python 和一般编程新手。目前正在学习类和对象,真的很挣扎。在这个特定示例中,我有一个 Animal 父类和一个 EggLayers 子类。EggLayers 类有一个方法来计算特定实例一周的鸡蛋产量,然后将该值追加到列表中。我有另一种方法可以计算鸡的终生产量。这个想法是,每周的总数从运行第一个方法开始进入一个列表,然后第二个方法对列表求和以返回实例的生存期总数。第一次运行良好,但是,当我第二次尝试运行第一个方法时,我得到一个 TypeError('int' 对象不可调用)。
我在代码中的各个地方尝试了 int()。也不要以为我在任何地方覆盖了 int() 函数。显然,这是导致此错误的两个最常见原因。如果我遇到上述任何一个问题,我认为它不会第一次运行。
class EggLayers(Animal):
"""A class for egg laying animals"""
type = "chicken"
def __init__(self, name, age, color, tag):
super().__init__(name, age, color, tag)
def eggs_week(self): # to calculate eggs/week and then append to list
self.eggs_list = []
self.eggs_day = int(input("Eggs today? "))
self.eggs_day = self.eggs_day
self.eggs_week = self.eggs_day * 7
self.eggs_list.append(self.eggs_week)
print(f"{self.name} laid {self.eggs_week} this week")
return self.eggs_week
def eggs_lifetime(self): # to sum the values in the list above
self.eggs_lifetime = sum(self.eggs_list)
print(f"Liftetime production for {self.name} is {self.eggs_lifetime}")
return self.eggs_lifetime
chicken1 = EggLayers('chicken1', 3, 'white', '002')
chicken1.eggs_week()
chicken1.eggs_lifetime()
chicken1.eggs_week() # Only throws an error the second time
答:
3赞
Tim Roberts
8/4/2023
#1
这是因为在你的函数中,你有eggs_week
self.eggs_week = self.eggs_day * 7
在那之后,不再是一个功能。它是一个整数。chicken1.eggs_week
您实际上不需要在函数名称中包含前缀,因为它已经是一个与 eggs 相关的类。此外,您计算的大多数值不需要在对象中保存为状态,因此它们不需要 。self.
更多此类内容:
class EggLayers(Animal):
"""A class for egg laying animals"""
type = "chicken"
def __init__(self, name, age, color, tag):
super().__init__(name, age, color, tag)
self.eggs_list = []
def per_week(self): # to calculate eggs/week and then append to list
eggs_day = int(input("Eggs today? "))
eggs_week = eggs_day * 7
self.eggs_list.append(eggs_week)
print(f"{self.name} laid {eggs_week} this week")
return eggs_week
def lifetime(self): # to sum the values in the list above
eggs_lifetime = sum(self.eggs_list)
print(f"Liftetime production for {self.name} is {eggs_lifetime}")
return eggs_lifetime
就我个人而言,我认为在这样的类方法中进行 I/O 是一种不好的做法。该类应包含与对象直接相关的功能。它不应该关心信息来自哪里。例如,现在,您不能轻松地使用它从文件或数据库中读取数据。
我会在类外有一个循环来请求输入,然后有一个类方法允许我传递该信息,例如 .但是,我没有在这里进行更改。add_week
评论
1赞
juanpa.arrivillaga
8/4/2023
我要强调的是,您停止了对实例属性的赋值,而是在方法中使用了局部变量
0赞
Ryan R. McKnight
8/4/2023
啊,所以要清楚,因为我的函数名和变量名是相同的,所以一个替换另一个。完全有道理。我一直在想,函数名称后面的()会将其与同名变量区分开来。非常感谢!
0赞
Tim Roberts
8/4/2023
不,所有的名字都是一样的。一个对象只有一个命名空间。同样的事情也发生在全球层面。说将从您的使用中删除正常的文件功能。open = 7
open
0赞
juanpa.arrivillaga
8/4/2023
@RyanR.McKnight本质上就像一个操作员。它作用于表达式的结果,表达式也是如此,它产生一个对象。然后,尝试调用该对象。但在本例中,是 ,但对象不可调用。你可以通过这样做得到同样的错误()
self.whatever
()
self.whaeter
int
int
f = 42
print(f())
评论
EggLayers.eggs_week
chicken1.eggs_lifetime()
__init__