You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

修改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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 16:35:24