令人困惑的二传手和吸气剂?为什么使用setter throw'str'对象不可调用?

时间:2018-02-05 15:58:36

标签: python class properties setter

我听说使用getter和setter函数(例如set_value()get_value())不是Pythonic,使用带有setter和getter的property对象总是更好。< / p>

我运行了下面的代码,收到错误'str' object is not callable'。当我搜索此错误时,我发现了很多代码示例,其中类具有属性和具有相同名称的方法(就像我在self.name中编写self.__name而不是__init__方法)。

但是我在属性之前使用了两个下划线 - 所以它不应该在这里发生。看起来当我尝试调用name.setter时,我实际上调用了一个属性,并收回了存储在self.__name中的字符串 - 然后它就是这个字符串,然后我试着调用别的东西。

但为什么呢?在setter的所有示例中,它们与属性具有相同的名称,并且不会导致问题。为什么会在这里抛出错误,我该如何解决?

class Dog():
    def __init__(self, name):
        self.__name = name

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

    @name.setter
    def name(self, name_in):
        self.__name = name_in

dog = Dog("Barbos")
print(dog.name)                 # this works
dog.name("Juchka")              # and this throws an error: 
                                # TypeError: 'str' object is not callable

1 个答案:

答案 0 :(得分:3)

你仍然在考虑这里的方法。 setter 不直接调用。而是在分配名称时调用setter。

使用作业:

dog.name = "Juchka"

Python将其转换为对setter方法的调用。

只需访问dog.name即可调用getter,getter方法返回一个字符串。调用是一个单独的表达式,用于查找对象以将调用应用于; dog.name("Juchka")首先执行dog.name,并将("Juchka")调用表达式应用于该属性查找的结果。属性查找返回"Barbos",而"Barbos"("Juchka")确实不起作用。

演示:

>>> dog = Dog("Barbos")
>>> dog.name
'Barbos'
>>> 'Barbos'("Juchka")  # what really happens when you try to call dog.name(...)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'str' object is not callable
>>> dog.name = "Juchka"
>>> dog.name
'Juchka'