8

TypeError: 'модуль' не является вызываемым объектом

30

При выполнении программы на 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 ответ(ов)

8

Вам необходимо понимать, что 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 также ссылается на сам модуль.

Чтобы логически разобраться с этой ошибкой, вы можете следовать этому процессу:

  1. Ошибка "module object is not callable" говорит мне о том, что мой код пытается вызвать что-то, что не может быть вызвано. Что же он пытается вызвать?
  2. "Код пытается вызвать socket. Это должно быть вызываемым! Является ли переменная socket тем, чем я думаю?"
  3. Я должен вывести значение переменной, чтобы проверить, что там действительно содержится: print(socket).

Если вы увидите, что socket ссылается на модуль, это и есть источник вашей ошибки. Ваша задача — исправить код, чтобы он вызывал именно класс внутри модуля, как показано в примере.

3

Вам следует обратить внимание на структуру импортов в 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() будет успешным.

Таким образом, ключевое различие в том, как вы импортируете: в первом случае вы получаете модуль, а во втором — непосредственно класс.

1

Для того чтобы сделать ваш класс доступным при импорте из другого скрипта, добавьте в основной файл __init__.py в каталоге вашего класса (YourClassParentDir) следующую строку:

from .YourClass import YourClass

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

from YourClassParentDir import YourClass
0

Краткий ответ: Вы вызываете файл/каталог как функцию вместо настоящей функции.

Читать дальше:

Такая ошибка возникает, когда вы импортируете модуль, думая, что это функция, и пытаетесь его вызвать. В 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()  # теперь все работает.
0

Вот ещё одна уловка, которую мне потребовалось время, чтобы понять, даже после прочтения этих сообщений. Я настраивал скрипт для вызова своих 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/

Если это не соответствует стандарту, пожалуйста, дайте знать.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь