修改Python类实例属性时出现TypeError: 'str' object is not callable错误
错误分析:TypeError: 'str' object is not callable
问题代码
class Airport: def __init__(self, code, city, country): self._code=code self._city=city self._country=country def __repr__(self): return "%s(%s,%s)"%(self._code, self._city, self._country) def getCode(self): return self._code @property def getCity(self): print('property') return self._city @property def getCountry(self): return self._country @getCity.setter def setCity(self,city): print('changecity') self._city=city @getCountry.setter def setCountry(self,country): self._country=country a1 = Airport("YXU", "London", "Canada") a2 = Airport("ABC", "Madrid", "Spain") a2.setCity("Athens") a2.setCountry("Greece")
触发的错误
执行a2.setCity("Athens")时出现:
TypeError: 'str' object is not callable
错误原因
问题出在Python @property装饰器的绑定逻辑上:
- 用
@getCity.setter装饰setCity方法时,Python不会创建一个名为setCity的可调用方法,而是把这个setter绑定到getCity这个属性上。 - 当你写
a2.setCity("Athens")时,Python会先尝试获取a2的setCity属性,但类里并没有定义这个属性,最终会返回self._city的当前值(也就是字符串"Madrid")。 - 你试图对这个字符串加括号调用,自然就会触发"str对象不可调用"的错误。
解决方法
属性的getter和setter必须使用同一个名称,然后通过属性赋值的方式触发setter,而不是调用方法。修改后的代码如下:
class Airport: def __init__(self, code, city, country): self._code=code self._city=city self._country=country def __repr__(self): return "%s(%s,%s)"%(self._code, self._city, self._country) def getCode(self): return self._code @property def city(self): print('property') return self._city @property def country(self): return self._country @city.setter def city(self,city): print('changecity') self._city=city @country.setter def country(self,country): self._country=country a1 = Airport("YXU", "London", "Canada") a2 = Airport("ABC", "Madrid", "Spain") a2.city = "Athens" # 用属性赋值触发setter a2.country = "Greece"
这样修改后,给a2.city赋值时会自动触发对应的setter方法,同时获取a2.city时也会触发getter逻辑,完全符合@property的使用规范。
内容的提问来源于stack exchange,提问作者Maggie Lau
相关产品推荐
相关产品推荐

