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

混淆Setter与Getter?调用Setter时为何触发‘str’ object is not callable错误?

解决Python中使用property时出现的'str' object is not callable错误

我完全懂你的困扰——明明已经抛弃了Java风格的get/set函数,改用Python更优雅的property来做属性控制,还特意用双下划线把内部属性设为私有,结果还是碰到了这个'str' object is not callable错误,而且常见的“属性与方法同名”的坑你已经避开了,这就更让人挠头对吧?别慌,咱们来拆解几个你可能没注意到的细节:

可能的原因1:不小心覆盖了property方法

虽然你用了双下划线的私有属性,但如果在__init__或者其他方法里,错误地给和property同名的实例属性赋值,就会把property装饰的方法给覆盖成字符串。比如下面这个错误示例:

class Person:
    def __init__(self):
        self.__name = "Alice"
        self.name = self.__name  # 这里踩坑了!把实例的name属性设为字符串,覆盖了@property的方法

    @property
    def name(self):
        return self.__name

这时候你实例化后,p.name直接是字符串"Alice",如果不小心写成p.name()(把属性当成方法调用),就会触发'str' object is not callable错误。

解决办法:
彻底避免给和property同名的实例属性直接赋值,所有内部状态都存在双下划线的私有属性里,比如self.__name,让property方法完全接管外部的属性访问。

可能的原因2:Setter方法里的赋值错误

如果你的property定义了setter,但在setter里错误地把值赋给property本身而不是私有属性,也会引发问题(甚至可能间接导致属性被覆盖)。比如:

class Person:
    def __init__(self):
        self.__age = 18

    @property
    def age(self):
        return self.__age

    @age.setter
    def age(self, value):
        self.age = value  # 这里错了!应该是self.__age = value

这段代码里,self.age = value会无限触发setter方法,最终可能导致栈溢出,但如果中途某个环节把age变成了字符串,后续访问也会触发相同的错误。

解决办法:
在setter方法里,一定要把值赋值给双下划线的私有属性,比如self.__age = value,确保修改的是内部存储,而不是触发property的访问逻辑。

可能的原因3:误把属性当成方法调用

有时候只是手滑——property是用来像访问普通属性一样使用的,不需要加括号。如果你写成了p.name()而不是p.name,那就是在尝试调用一个字符串,自然会报错。

解决办法:
去掉多余的括号,直接用实例.属性名的方式访问或赋值。

正确的property使用示例

最后给你一个标准的正确写法,参考这个来调整你的代码:

class Person:
    def __init__(self):
        # 内部用双下划线私有属性存储
        self.__name = "Alice"
        self.__age = 18

    @property
    def name(self):
        # Getter:返回私有属性
        return self.__name

    @name.setter
    def name(self, value):
        # Setter:可以加验证逻辑
        if not isinstance(value, str):
            raise ValueError("Name must be a string")
        self.__name = value  # 赋值给私有属性

    @property
    def age(self):
        # 只读属性,没有setter
        return self.__age

使用的时候:

p = Person()
print(p.name)  # 输出 "Alice"
p.name = "Bob"
print(p.name)  # 输出 "Bob"
print(p.age)   # 输出 18
# p.age = 20  # 会报错,因为age是只读属性

内容的提问来源于stack exchange,提问作者igor Smirnov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 04:06:04