我有一个简单的脚本:
1 2 3 4 5 6
| 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') |
但是,每当我尝试运行脚本时,python都会引发一个错误:
1 2 3
| Traceback (most recent call last):
File"python", line 2, in <module>
TypeError: 'list' object is not callable |
这个错误是什么意思?我为什么要买?我该怎么修?
- 确保你的问题首先出现在谷歌上!尼斯问答
- fwiw,我认为这个问题对于这个场景来说是一个更好的规范:typeerror:当我试图访问一个列表时,"list"对象是不可调用的,我将它用作dupe目标。
- 我认为这个例子令人困惑,因为它没有重新定义导致这个错误的内置名称。我在exec("class B: pass
b = B()
b()")上也有类似的错误。大多数获得list object is not callable的人没有重新定义list的名字。
- @我不同意这一点。发布错误是因为我重新定义了内置名称list。正因为如此,我不能再使用名称list的原值。因为没有实现某个特定的方法,所以导致了获取Otoh的错误。我知道并不是所有的TypeError都是由于重新定义内置名称而引起的,但是在qucik上搜索会显示许多标题为"typeerror:"object i s not called"的问题都犯了重新定义内置名称的错误。
- 不,试试这个。错误与此线程的标题完全相同。此消息的含义是列表类型的实例不是可调用对象。
- 我知道,@gribouillis.我知道并非所有的TypeError都是因为重新定义了内置名称。我要说的是,我在python标签中看到的关于TypeError的大量问题是因为op重新定义了一个内置名称。因此,创建一个规范的Q&A日志,特别处理重新定义内置名称的主题以及它通常导致的错误,是有好处的。
- 我同意这是一个很好的错误案例,有一个规范的问答。但我也认为您的答案应该提到其他可能导致相同错误消息的场景。像a=[1]; b=a(0)这样的东西很常见,尽管我想我们可以把这种用法归类为打字错误…
- @我同意你的看法。我的答案中没有包含这样的案例,因为我认为我们已经有了一个很好的问答:stackoverflow.com/questions/5735841/&hellip;。我只是不想重复信息。我还觉得这有点像拖鞋坡。自言自语:"在什么时候,你会停止称一个TypeError事业为共同点?"这可能只是我的懒惰,尽管我没有找出共同的原因。但如果你不认为这会导致更完整的问答,我会努力补充。
- 在结尾加上一个简短的参考,可能在之后。希望很多人会通过搜索错误消息来访问此页面,因此如果他们出于some_list(idx)的原因来到这里,最好将他们重定向到另一个问题。
- 那么现有的stackoverflow.com/questions/31087111/&hellip;?第二次谷歌为我点击错误信息。
- @安德拉斯迪克,这是你提出的一个非常正确的观点。这个答案很好。这是我一直使用的欺骗目标。但我创建这个问答有两个主要原因。简而言之:(1)imho,另一个答案深入探讨了名称空间和全局查找的细节,而不仅仅是关注主要问题。(2)我认为,如果答案能更详细地讨论一下内置的内容,使文章更为笼统,那就更好了。现在,它似乎只是本地化了。
- 你不喜欢一个答案并不是让你自己的问题成为一对的正当理由。如果问题不好(没有mcve或类似问题),并且在不使现有答案无效的情况下无法编辑成形状,那么我完全支持创建新的、更好的、规范的问答,但这不适用于答案。我们有一个投票系统,让社区决定哪个答案最好。如果你写一个更好的答案,你的答案最终会达到顶峰。通过创建自己的问答表,你将使人们在写现有答案和投票时所做的所有努力无效。
- 我很欣赏阿兰费的评论。我理解你的担心。我一般同意你说的话。我之所以发布一个新的问答,而不是发布另一个与Andras相关的问题的答案,是因为我觉得与Andras相关的帖子已经有了一个特定的焦点。是的,我对安德拉斯的评论只强调了答案,但我仍然认为答案是有用的,并决定最好创建一个新的问题和一对单独解决这个主题。我本可以把这个问题塑造成更适合我的主题,但我觉得这样做会使选择的最上面的答案失效。
- (继续从上面的评论)但是,我不同意我的回答是无效的。如果我在安德拉斯链接的问题上发布了一个答案,我会使当前的顶级答案无效吗?我不这么认为。我看不出在新的问答栏上贴出的答案实际上是如何不同的。至于投票无效,我还是要恭敬地表示不同意。这仍然是社区的选择,选择这个新的问答我创建的,对一个安德拉斯联系。我试图证明为什么我在创建一个新的Q&A组合时做出了正确的决定。
- 顺便说一下,我忘了提一下:这个问题正在meta上讨论。你可以把你的理论基础贴在那里。
在完全理解错误的含义和解决方法之前,了解Python中的内置名称是什么很重要。
什么是内置名称?
在python中,内置名称是python解释器已经分配了一个预定义值的名称。该值可以是函数或类对象。默认情况下,无论作用域是什么,这些名称都是可用的。分配给这些名称的一些值代表了Python语言的基本类型,而其他值则很简单。
从最新版本的python-3.6.2开始,目前有61个内置名称。可以在"文档"部分的"内置函数"中找到名称及其使用方法的完整列表。
但是,需要注意的一点是,Python不会阻止您重新分配内置名称。内置名称不被保留,python也允许将它们用作变量名。
下面是一个使用dict内置的示例:
1 2 3 4
| >>> dict = {}
>>> dict
{}
>>> |
如您所见,python允许我们分配dict名称来引用dictionary对象。
"typeerror:'list'对象不可调用"是什么意思?
简单地说,出现错误的原因是您在脚本中重新分配了内置名称list:
执行此操作时,会覆盖内置名称的预定义值。这意味着您不能再使用list的预定义值,该值是表示Python列表的类对象。
因此,当您试图使用list类从range对象创建新列表时:
1
| myrange = list(range(1, 10)) |
python引发了一个错误。错误显示"list"对象不可调用的原因是如上所述,名称list引用了一个list对象。因此,上述操作等同于:
1
| [1, 2, 3, 4, 5](range(1, 10)) |
这当然没有道理。不能调用列表对象。
如何修复错误?
如果遇到类似的错误,比如说"对象不可调用",那么很可能在代码中使用了内置名称作为变量。在这种情况下,修复程序与重命名有问题的变量一样简单。例如,要修复上述代码,我们可以将list变量重命名为ints:
1 2 3 4 5 6
| 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') |
官方的python风格指南pep8包含了许多关于命名变量的建议。
这是新的和旧的python用户所犯的一个非常常见的错误。这就是为什么总是避免使用内置名称作为变量的原因,如str、dict、list、range等。
当您尝试使用内置名称作为变量时,许多linter和ide都会发出警告。如果你经常犯这样的错误,那么在这些项目中投资可能是值得的。
我没有重命名内置名称,但仍然得到"typeerror:'list'对象不可调用"。给出了什么?
上述错误的另一个常见原因是试图使用括号(()而不是方括号([]对列表进行索引)。例如:
1 2 3 4 5 6 7
| >>> 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"对象。
您已经重写了Python的内置方法list。
1
| mylist = [1, 2, 3, 4, 5] # just use any other name than `list` |
- 是的,我知道。这篇文章的意思是作为一个规范的问答:—)
- @Christiandean inbuilt list是一个方法或可调用类。而您定义的列表是该类的实例,并且不可调用。
- @hspandher如果你注意到,问和答的人是一样的。
- 我知道,我知道。正如我上面所说,我把这篇文章写成了一个癌症问答。请看这里。
- @冷速哎呀错过了。我不知道StackOverflow是否鼓励这样做。
- 当然是鼓励的。请参阅stackoverflow.com/help/self-answer
这是mcve!
1 2 3 4
| >>> []()
Traceback (most recent call last):
File"<stdin>", line 1, in <module>
TypeError: 'list' object is not callable |
也可以试试{}()和()()。消息TypeError: 'X' object is not callable表示您编写了expression(some_arguments),其中expression是X类型的实例,并且此类型不支持在函数调用语法中使用。大多数时候,编写这个代码是因为您认为expression是一个函数或其他可调用类型。
- 我不明白他们的落选。我的回答是"我该如何修复错误?"部分。python不禁止重新定义名称"list",但它拒绝调用列表类型的实例。对于所有实际调试目的,此答案都有效。