Python面向对象编程初始化对象时遇TypeError参数数量不匹配错误
问题分析与解决方案
嘿,我来帮你排查这个错误!你遇到的TypeError: get_name() takes 1 positional argument but 2 were given,根源其实是几个小问题叠加导致的,咱们一步步拆解:
1. Getter方法定义冗余参数
你的get_name方法多写了一个name参数:
def get_name(self, name): return self.__name
Getter方法的作用就是返回实例的私有属性,只需要接收self这一个参数就够了。当Python尝试调用这个方法时,会自动传入self,但因为你定义了两个参数,它就会误以为你传入了2个参数,直接触发报错。
2. Property参数顺序搞反了
Python的property函数参数顺序是固定的:property(fget=None, fset=None, fdel=None, doc=None)——也就是先写getter方法,再写setter方法。但你写的是:
name=property(set_stats, get_name)
这就把setter放到了getter的位置,当你在__init__里执行self.name=name时,会错误地触发getter方法,而不是setter,这也是参数不匹配的诱因之一。
3. 所有属性共用同一个setter不合理
你的set_stats方法是用来一次性设置所有属性的,但每个property应该对应独立的setter方法——比如设置name的setter只需要接收name参数,专门处理self.__name,而不是一次性操作所有属性。
修复后的完整代码
下面是修正后的代码,关键修改点我都标出来了:
class basicbot: # constructor def __init__(self, name, size, power, speed, health): # 直接初始化私有属性,避免触发property的setter self.__name = name self.__size = size self.__power = power self.__speed = speed self.__health = health # 每个属性对应独立的setter方法 def set_name(self, name): self.__name = name def set_size(self, size): self.__size = size def set_power(self, power): self.__power = power def set_speed(self, speed): self.__speed = speed def set_health(self, health): self.__health = health # printing method def __str__(self): return "name is %s, size is %s, power is %s, speed is %s, health is %s" % ( self.get_name(), self.get_size(), self.get_power(), self.get_speed(), self.get_health() ) # 修正getter方法,去掉多余参数 def get_name(self): return self.__name def get_size(self): return self.__size def get_power(self): return self.__power def get_speed(self): return self.__speed def get_health(self): return self.__health # 正确定义property:先getter,再setter name = property(get_name, set_name) size = property(get_size, set_size) power = property(get_power, set_power) speed = property(get_speed, set_speed) health = property(get_health, set_health) # test code to make sure basicbot works bot1 = basicbot("basicbot", 2, 3, 4, 5) print(bot1) # 可以测试property的赋值功能 bot1.name = "updated_bot" print(bot1)
额外优化建议
你还可以用Python的装饰器语法来定义property,代码会更简洁易读:
class basicbot: def __init__(self, name, size, power, speed, health): self.__name = name self.__size = size self.__power = power self.__speed = speed self.__health = health @property def name(self): return self.__name @name.setter def name(self, name): self.__name = name # 其他属性同理,用@property和@属性.setter装饰器即可 # ... 省略其他属性的getter和setter def __str__(self): return "name is %s, size is %s, power is %s, speed is %s, health is %s" % ( self.name, self.size, self.power, self.speed, self.health )
这样写不需要手动调用property函数,代码结构更清晰。
内容的提问来源于stack exchange,提问作者Random person
相关产品推荐
相关产品推荐

