为什么像`str = str(...)`这样的代码会导致TypeError错误,但只有第二次会出错?

103

我有一些代码,如下所示:

def example(parameter):
    global str
    str = str(parameter)
    print(str)

example(1)
example(2)

第一次调用example可以正常工作,但第二次出现错误,错误信息如下:

Traceback (most recent call last):
  File "test.py", line 7, in <module>
    example(2)
  File "test.py", line 3, in example
    str = str(parameter)
TypeError: 'str' object is not callable
为什么会发生这种情况,我该怎么解决?
如果你在一个交互式的会话中遇到了这样的问题,想要在不重启解释器的情况下解决问题,请查看如何恢复被意外覆盖的内置函数?

我对问题进行了重大编辑,以生成一个适当的[mre] - 最初有很多与问题无关的代码(这些代码没有在任何答案中考虑 - 任何其他问题都会使问题缺乏适当的焦点)。我还删除了一个关于原始代码的后续回复,以及如何在上下文中精确修复它 - 因为这不是讨论论坛 - Karl Knechtel
这个问题已经成为一个有用的规范,所以我希望它看起来尽可能好。虽然最初是11年前提出的,但我想提醒大家在发布之前尝试追踪和理解问题。 - Karl Knechtel
20个回答

161

代码中提到:

global str
str = str(parameter)

你正在重新定义str()的含义。 str是Python中字符串类型的内置名称,而您不想更改它。

为局部变量使用其他名称,并删除global语句。

请注意,如果在Python REPL中使用此类代码,则对全局str的赋值将持久存在,直到您采取某些措施。您可以重新启动解释器或del str。后者有效,因为str默认情况下实际上不是已定义的全局变量 - 而是通常在回退中找到(即builtins标准库模块,在启动时特别导入并给予全局名称__builtins__)。


7
不建议使用该函数,但可以使用str()函数, 它也可以作为__builtins__.str()使用。当然,在99.9999%的情况下使用它是不可取的,我想。 - n611x007
在原始代码中,“global”语句是必需的,以避免不同的问题。重命名后,它变得无用,但并不直接有害。 - Karl Knechtel

121

虽然不在您的代码中,但在尝试进行字符串格式化时,另一个难以发现的错误是缺少%字符:

"foo %s bar %s coffee"("blah","asdf")

但它应该是:

"foo %s bar %s coffee"%("blah","asdf")
缺少的%符号会导致相同的TypeError: 'str' object is not callable错误。

拥有同名的属性和方法,将方法覆盖为字符串,然后尝试执行该方法/字符串也会导致 TypeError: 'str' object is not callable。 - Puggan Se

26

在我的情况下,我有一个类,其中包含一个方法和一个同名的字符串属性。我试图调用该方法,但却获取了该字符串属性。


1
可能记录阴影效果并添加类似严格模式的功能会更好,因为这样可以在发生RuntimeWarning时进行警告。但是,根据规范,使用Python替换属性和方法是完全有效的。 - ThorSummoner

26
请注意,TypeError: 'str' object is not callable 表示尝试调用字符串(即,任何先前分配为字符串的名称)时出现了错误。使用其他任何内置方法作为变量名也可能导致完全相同的错误消息。

19

如果您有变量str并尝试调用str()函数,则可能会出现此错误。


13

每当发生这种情况时,只需执行以下操作(它也发布在上面)

>>> del str

那应该就解决了。


8
另一个例子是:干扰带有 __repr__ 函数的对象,其中一个 format() 调用会以非透明方式失败。
在我们的案例中,我们在 __repr__ 上使用了 @property 装饰器,并将该对象传递给了 format()@property 装饰器导致 __repr__ 对象被转换为字符串,这导致了 str 对象不可调用的错误。

很难理解所描述的情况。请在答案中添加 [mre]。 - Karl Knechtel

6

请检查您的输入参数,并确保没有一个名为type。如果有,那么您将会遇到冲突并得到这个错误。


5

我也遇到了同样的错误。在我的情况下,不是因为变量名为str。而是因为我用str参数命名了一个函数,而且变量也是同样的名称。

same_name = same_name(var_name: str)

我在一个循环中运行它。第一次正常运行。第二次出现了这个错误。将变量重命名为与函数名称不同的名称可以解决此问题。因此,我认为这是因为Python在作用域中一旦关联了一个函数名称,第二次尝试将左侧部分(same_name =)关联到函数调用并检测到缺少str参数,然后抛出该错误。


5
str = 'Hello World String'    
print(str(10)+' Good day!!')

我也遇到了使用上面代码时出现的问题,这是因为我们重写了 str() 函数。

解决方法:

string1 = 'Hello World String'
print(str(10)+' Good day!!')

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接