TypeError: 'модуль' не является вызываемым объектом
При выполнении программы на Python я столкнулся с ошибкой следующего рода:
File "C:\Users\Administrator\Documents\Mibot\oops\blinkserv.py", line 82, in __init__
self.serv = socket(AF_INET, SOCK_STREAM)
TypeError: 'module' object is not callable
В чем заключается проблема? Я не могу понять, почему возникает эта ошибка.
Как мне её решить?
5 ответ(ов)
Вам необходимо понимать, что socket
— это модуль, содержащий класс socket
. Чтобы создать экземпляр этого класса, вам нужно использовать конструкцию socket.socket(...)
или импортировать класс socket
напрямую с помощью from socket import socket
.
Пример кода:
>>> import socket
>>> socket
<module 'socket' from 'C:\Python27\lib\socket.pyc'>
>>> socket.socket
<class 'socket._socketobject'>
>>>
>>> from socket import socket
>>> socket
<class 'socket._socketobject'>
Ошибка, с которой вы столкнулись, означает следующее: "объект модуля не вызывается". Это происходит потому, что ваш код пытается вызвать объект модуля, который не может быть вызван как функция. Вы пытаетесь обратиться к классу внутри этого модуля, при этом у вас переменная с названием socket
также ссылается на сам модуль.
Чтобы логически разобраться с этой ошибкой, вы можете следовать этому процессу:
- Ошибка "
module object is not callable
" говорит мне о том, что мой код пытается вызвать что-то, что не может быть вызвано. Что же он пытается вызвать? - "Код пытается вызвать
socket
. Это должно быть вызываемым! Является ли переменнаяsocket
тем, чем я думаю?" - Я должен вывести значение переменной, чтобы проверить, что там действительно содержится:
print(socket)
.
Если вы увидите, что socket
ссылается на модуль, это и есть источник вашей ошибки. Ваша задача — исправить код, чтобы он вызывал именно класс внутри модуля, как показано в примере.
Вам следует обратить внимание на структуру импортов в Python и то, как они работают с модулями и классами.
Если ваш файл YourClass.py выглядит следующим образом:
class YourClass:
# ......
И вы пытаетесь использовать import следующим образом:
from YourClassParentDir import YourClass # подразумевает файл YourClass.py
Вы получите ошибку TypeError: 'module' object is not callable, если попытаетесь вызвать YourClass()
. Это происходит потому, что при таком импорте вы импортируете сам модуль, а не класс из него.
Однако, если вы используете:
from YourClassParentDir.YourClass import YourClass # подразумевает класс YourClass
или же:
import YourClassParentDir.YourClass
YourClassParentDir.YourClass.YourClass()
то все будет работать корректно, потому что в этом случае вы импортируете именно класс YourClass
, и дальнейший вызов YourClass()
будет успешным.
Таким образом, ключевое различие в том, как вы импортируете: в первом случае вы получаете модуль, а во втором — непосредственно класс.
Для того чтобы сделать ваш класс доступным при импорте из другого скрипта, добавьте в основной файл __init__.py
в каталоге вашего класса (YourClassParentDir) следующую строку:
from .YourClass import YourClass
После этого вы сможете создать экземпляр вашего класса, импортировав его в другой скрипт следующим образом:
from YourClassParentDir import YourClass
Краткий ответ: Вы вызываете файл/каталог как функцию вместо настоящей функции.
Читать дальше:
Такая ошибка возникает, когда вы импортируете модуль, думая, что это функция, и пытаетесь его вызвать. В Python модуль – это файл с расширением .py. Пакеты (каталоги) также можно считать модулями.
Предположим, у меня есть файл create.py. В этом файле есть функция следующего вида:
# внутри create.py
def create():
pass
Теперь, в другом файле кода, если я сделаю вот так:
# внутри файла main.py
import create
create() # здесь create ссылается на create.py, поэтому create.create() будет работать
Это приведет к ошибке, так как я пытаюсь вызвать файл create.py как функцию. Поэтому мне нужно сделать следующее:
from create import create
create() # теперь все работает.
Вот ещё одна уловка, которую мне потребовалось время, чтобы понять, даже после прочтения этих сообщений. Я настраивал скрипт для вызова своих Python-скриптов, и у меня также возникла ошибка «модуль не вызываем».
Моя проблема заключалась в том, что я делал следующее:
from mypackage.bin import myscript
...
myscript(...)
Хотя на самом деле мне нужно было сделать так:
from mypackage.bin.myscript import myscript
...
myscript(...)
В итоге, проверьте структуру вашей упаковки и модулей.
Что я пытаюсь сделать, так это создать каталог scripts, который не содержит расширение *.py, и при этом сохранить модули 'bin' в mypackage/bin, где они имеют расширение *.py. Я новичок в упаковке и стараюсь следовать стандартам так, как я их интерпретирую. Итак, у меня в корне проекта следующая структура:
setup.py
scripts/
script1
mypackage/
bin/
script1.py
subpackage1/
subpackage_etc/
Если это не соответствует стандарту, пожалуйста, дайте знать.
Как импортировать другие файлы Python?
Как применить функцию к двум столбцам DataFrame в Pandas
Как клонировать список, чтобы он не изменялся неожиданно после присваивания?
Преобразование списка словарей в DataFrame pandas
Ошибка: "'dict' объект не имеет метода 'iteritems'"