为什么“example = list(...)”会导致“TypeError:'list'对象不可调用”?[重复]
- 2024-12-04 08:56:00
- admin 原创
- 153
问题描述:
我尝试使用 REPL 教程中的这段代码:
example = list('easyhoss')
教程说example
应该等于一个列表['e', 'a', 's', 'y', 'h', 'o', 's', 's']
。但我却得到了一个错误:
>>> example = list('easyhoss')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'list' object is not callable
为什么会发生这种情况?
解决方案 1:
似乎您已经用指向类的相同名称遮蔽了list
指向类的内置名称。以下是示例:
>>> example = list('easyhoss') # here `list` refers to the builtin class
>>> list = list('abc') # we create a variable `list` referencing an instance of `list`
>>> example = list('easyhoss') # here `list` refers to the instance
Traceback (most recent call last):
File "<string>", line 1, in <module>
TypeError: 'list' object is not callable
我相信这是相当明显的。Python 将对象名称(函数和类也是对象)存储在命名空间(以字典的形式实现)中,因此您可以在任何范围内重写几乎任何名称。它不会显示为某种错误。您可能知道,Python 强调“特殊情况不足以打破规则”。您面临的问题背后有两条主要规则:
命名空间。Python 支持嵌套命名空间。理论上,你可以无限地嵌套它们。正如我已经提到的,它们基本上是名称和对相应对象的引用的字典。你创建的任何模块都有自己的“全局”命名空间,尽管实际上它只是相对于该特定模块的本地命名空间。
作用域。当你引用一个名称时,Python 运行时会在本地命名空间中查找它(相对于引用),如果这样的名称不存在,它会在更高级别的命名空间中重复尝试。这个过程一直持续,直到没有更高级别的命名空间。在这种情况下,你会得到一个
NameError
。内置函数和类驻留在特殊的高阶命名空间中__builtins__
。如果你在模块的全局命名空间中声明一个变量list
,解释器将永远不会在更高级别的命名空间(即)中搜索该名称。类似地,假设你在模块的一个函数内__builtins__
创建一个变量,并在该模块中创建另一个变量。那么,如果你在函数内部引用,你将永远不会得到全局的,因为在本地命名空间中有一个——解释器没有必要在其他地方搜索它。var
`varvar
var`var
这是一个简单的例子。
>>> example = list("abc") # Works fine
>>>
>>> # Creating name "list" in the global namespace of the module
>>> list = list("abc")
>>>
>>> example = list("abc")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'list' object is not callable
>>> # Python looks for "list" and finds it in the global namespace,
>>> # but it's not the proper "list".
>>>
>>> # Let's remove "list" from the global namespace
>>> del list
>>> # Since there is no "list" in the global namespace of the module,
>>> # Python goes to a higher-level namespace to find the name.
>>> example = list("abc") # It works.
因此,如您所见,Python 内置函数并没有什么特别之处。您的案例只是通用规则的一个例子。您最好使用突出显示名称阴影的 IDE(例如 PyCharm 的免费版本,或带有 Python 插件的 Atom)来避免此类错误。
您可能想知道什么是“可调用”,在这种情况下,您可以阅读这篇文章。list
作为一个类,它是可调用的。调用类会触发实例构造和初始化。实例也可能是可调用的,但list
实例不是。如果您对类和实例之间的区别更加困惑,那么您可能需要阅读文档(非常方便,同一页面涵盖了命名空间和作用域)。
如果您想了解有关内置函数的更多信息,请阅读Christian Dean 的回答。
PS当您启动交互式 Python 会话时,您会创建一个临时模块。
解决方案 2:
在您完全理解错误的含义以及如何解决之前,了解 Python 中的内置名称是什么非常重要。
什么是内置名称?
在 Python 中,内置名称是Python 解释器已分配预定义值的名称。该值可以是函数或类对象。无论范围如何,这些名称始终默认可用。分配给这些名称的一些值代表 Python 语言的基本类型,而其他一些则简单有用。
自最新版本的 Python - 3.6.2起,目前有61 个内置名称。 可以在文档的内置函数部分找到名称的完整列表及其使用方法。
然而,需要注意的一点是,Python不会阻止您重新分配内置名称。内置名称不是保留的,Python 也允许它们用作变量名。
dict
以下是使用内置功能的示例:
>>> dict = {}
>>> dict
{}
>>>
如你所见,Python 允许我们分配名称dict
来引用字典对象。
“TypeError:'list'对象不可调用”是什么意思?
简单地说,发生错误的原因是因为您在脚本中重新分配了内置名称 :list
list = [1, 2, 3, 4, 5]
当你这样做时,你覆盖了内置名称的预定义值。这意味着你不能再使用预定义值list
,它是表示 Python 列表的类对象。
因此,当您尝试使用该类list
从对象创建新列表时range
:
myrange = list(range(1, 10))
Python 引发了一个错误。错误显示“‘list’ 对象不可调用”的原因是,如上所述,该名称list
指的是列表对象。因此,上述操作相当于执行以下操作:
[1, 2, 3, 4, 5](range(1, 10))
这当然毫无意义。您无法调用列表对象。
我该如何修复这个错误?
假设您有如下代码:
list = [1, 2, 3, 4, 5]
myrange = list(range(1, 10))
for number in list:
if number in myrange:
print(number, 'is between 1 and 10')
运行上述代码会产生以下错误:
Traceback (most recent call last):
File "python", line 2, in <module>
TypeError: 'list' object is not callable
如果您收到类似错误(如上面的错误,提示“对象不可调用”),则可能是您在代码中使用了内置名称作为变量。在这种情况下以及其他情况下,修复方法很简单,只需重命名有问题的变量即可。例如,要修复上述代码,我们可以将list
变量重命名为ints
:
ints = [1, 2, 3, 4, 5] # Rename "list" to "ints"
myrange = list(range(1, 10))
for number in ints: # Renamed "list" to "ints"
if number in myrange:
print(number, 'is between 1 and 10')
PEP8——官方 Python 风格指南——包含许多关于命名变量的建议。
这是新老 Python 用户常犯的一个错误。因此,务必避免使用内置名称作为变量,例如、 、str
、dict
等。list
`range`
当您尝试使用内置名称作为变量时,许多 linters 和 IDE 都会发出警告。如果您经常犯此错误,那么投资其中一种程序可能是值得的。
我没有重命名内置名称,但仍然收到“TypeError:'list' 对象不可调用”的错误提示。这是怎么回事?
()
导致上述错误的另一个常见原因是尝试使用括号 ( ) 而不是方括号 ( )来索引列表[]
。例如:
>>> lst = [1, 2]
>>> lst(0)
Traceback (most recent call last):
File "<pyshell#32>", line 1, in <module>
lst(0)
TypeError: 'list' object is not callable
要了解完整问题的解释以及如何修复它,请参阅TypeError:尝试访问列表时无法调用“list”对象。
解决方案 3:
如果你处于交互式会话中,并且不想重新启动,你可以使用以下命令删除阴影
del list
解决方案 4:
在周一早上犯的愚蠢错误中,当尝试访问列表中的项目时使用圆括号而不是方括号也会给出相同的错误消息:
l=[1,2,3]
print(l[2])#GOOD
print(l(2))#BAD
TypeError:'list' 对象不可调用
解决方案 5:
您可能在代码中对变量使用了内置名称“list”。如果您使用的是 Jupyter 笔记本,有时即使您将该变量的名称从“list”更改为其他名称并重新运行该单元格,您仍可能会收到错误。在这种情况下,您需要重新启动内核。为了确保名称已更改,请在创建列表对象时单击单词“list”,然后按Shift
+ Tab
,并检查 Docstring 是否将其显示为空列表。
解决方案 6:
为什么会TypeError: 'list' object is not callable
出现?
解释:
这是因为您list
之前将其定义为变量(我很确定),所以它将是一个列表,而不再是函数,这就是为什么每个人都不应该将变量命名为函数,下面与您现在所做的相同:
>>> [1,2,3]()
Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
[1,2,3]()
TypeError: 'list' object is not callable
>>>
因此您需要它作为的默认函数list
,如何检测它是否是?只需使用:
>>> list
<class 'list'>
>>> list = [1,2,3]
>>> list
[1, 2, 3]
>>> list()
Traceback (most recent call last):
File "<pyshell#4>", line 1, in <module>
list()
TypeError: 'list' object is not callable
>>>
如何检测变量名是否为函数?好吧,只需简单看看它是否具有不同的颜色,或使用如下代码:
>>> 'list' in dir(__builtins__)
True
>>> 'blah' in dir(__builtins__)
False
>>>
在此之后,您应该知道为什么会TypeError: 'list' object is not callable
出现这种情况。
好的,那么现在...
如何修复这个TypeError: 'list' object is not callable
错误?
代码:
您必须执行以下操作之一__builtins__.list()
:
>>> list = [1,2,3]
>>> __builtins__.list()
[]
>>>
或者使用[]
:
>>> list = [1,2,3]
>>> []
[]
>>>
list
或者从内存中删除变量:
>>> list = [1,2,3]
>>> del list
>>> list()
[]
>>>
或者只是重命名变量:
>>> lst = [1,2,3]
>>> list()
[]
>>>
PS 我猜最后一个是最优选的:-)
有很多可行的解决方案。
参考:
‘id’ 在 Python 中是一个错误的变量名
如何使用关键字作为变量名?
如何在python中使用保留关键字作为变量的名称?
解决方案 7:
通过显示它来找出你分配给“列表”的内容
>>> print(list)
如果它有内容,你必须用
>>> del list
现在再次显示“列表”,并期望
<class 'list'>
看到此信息后,您可以继续复制。
解决方案 8:
我因为另一个原因而收到此错误:
我无意中创建了一个空白列表,__init__
该列表与我试图调用的方法同名(我刚刚完成了一些重构,不再需要该变量,但我在清理时错过了它)。因此,当我实例化该类并尝试调用该方法时,它认为我引用的是列表对象,而不是方法:
class DumbMistake:
def __init__(self, k, v):
self.k = k
self.v = v
self.update = []
def update(self):
// do updates to k, v, etc
if __name__ == '__main__':
DumbMistake().update('one,two,three', '1,2,3')
因此,它尝试将两个字符串分配给 self.update[],而不是调用 update() 方法。删除变量后,一切按预期运行。希望这对某些人有所帮助。
解决方案 9:
您已经为 list 分配了一个值。
因此,list()
当它是变量时,您不能使用它。通过按计算机上的+
重新启动 shell 或 IDE 。
希望这也能奏效。Ctrl
`F6`
解决方案 10:
我发现自己遇到此错误是因为我有一个方法返回一个列表,而我给了该列表一个@property
装饰器。我忘记了装饰器,而是直接调用了装饰器,method()
结果method
出现了同样的错误。
解决方案 11:
为什么会出现错误?
因为您已在当前内核中将任何列表命名为“列表”。
例如:导入运算符
list = [1, 4, 5, 7, 9, 11]
#you are naming list as "list"
print("The sum is : ", end="")
print(list(itertools.accumulate(list1)))
print("The product is : ", end="")
print(list(itertools.accumulate(list1, operator.mul)))
解决方法:
只需重新启动内核即可。