Вопрос-Ответ

Why does "example = list(...)" result in "TypeError: 'list' object is not callable"? [duplicate]

Почему "example = list (...)" приводит к "TypeError: объект 'list' не вызывается"?

Я попытался использовать этот код из руководства в 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 подчеркивает, что "особые случаи недостаточно особенные, чтобы нарушать правила". И за проблемой, с которой вы столкнулись, стоят два основных правила.:


  1. Пространства имен. Python поддерживает вложенные пространства имен. Теоретически вы можете бесконечно вкладывать их. Как я уже упоминал, по сути, это словари имен и ссылок на соответствующие объекты. Любой создаваемый вами модуль получает свое собственное "глобальное" пространство имен, хотя на самом деле это просто локальное пространство имен по отношению к этому конкретному модулю.



  2. Область видимости. Когда вы ссылаетесь на имя, среда выполнения Python ищет его в локальном пространстве имен (относительно ссылки) и, если такое имя не существует, повторяет попытку в пространстве имен более высокого уровня. Этот процесс продолжается до тех пор, пока не останется более высоких пространств имен. В этом случае вы получаете NameError. Встроенные функции и классы находятся в специальном пространстве имен высокого порядка __builtins__. Если вы объявите переменную с именем list в глобальном пространстве имен вашего модуля, интерпретатор никогда не будет искать это имя в пространстве имен более высокого уровня (то есть __builtins__). Аналогично, предположим, вы создаете переменную var внутри функции в вашем модуле и другую переменную var в модуле. Тогда, если вы ссылаетесь на var внутри функции, вы никогда не получите глобальное 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 или Atom с плагинами Python), которая выделяет затенение имен, чтобы избежать подобных ошибок.

Вам также может быть интересно, что такое "вызываемый объект", и в этом случае вы можете прочитать этот пост. list, будучи классом, вызывается. Вызов класса запускает создание экземпляра и инициализацию. Экземпляр также может быть вызываемым, но list экземпляры таковыми не являются. Если вы еще больше озадачены различием между классами и экземплярами, то, возможно, захотите прочитать документацию (что весьма удобно, на той же странице описаны пространства имен и области видимости).

Если вы хотите узнать больше о встроенных компонентах, пожалуйста, прочтите ответ Кристиана Дина .

P.S. Когда вы запускаете интерактивный сеанс 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 .

Таким образом, когда вы пытались использовать list класс для создания нового списка из range объекта:

myrange = list(range(1, 10))

Python выдал ошибку. Причина, по которой в ошибке говорится "объект 'list' недоступен для вызова", заключается в том, что, как было сказано выше, имя list ссылалось на объект list . Таким образом, вышесказанное было бы эквивалентно выполнению:

[1, 2, 3, 4, 5](range(1, 10))

Что, конечно, не имеет смысла. Вы не можете вызвать объект list .

Как я могу исправить ошибку?

Предположим, у вас есть код, подобный следующему:

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 и т.д.

Многие линтеры и 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' не вызывается


2024-01-03 17:23 python list