TypeError: об'єкт 'module' не може викликатись


543
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

Чому я отримую цю помилку? Я збентежений.

Що потрібно знати, щоб відповісти на моє запитання?


8
Одного разу я отримав цю помилку, оскільки у мене була як (глобальна) змінна, так і функція з тим же ім'ям.
remustata

Відповіді:


563

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'>

Ось що означає повідомлення про помилку:
Він говорить module object is not callable, тому що ваш код викликає об'єкт модуля . Об'єкт модуля - це тип речі, який ви отримуєте при імпорті модуля. Що ви намагалися зробити, це викликати об’єкт класу в об'єкті модуля, який має те саме ім'я, що і модуль, який його містить.

Ось спосіб логічно зламати подібні помилки:

  • " module object is not callable. Python повідомляє мені свій код, намагаючись викликати те, що неможливо викликати. Який код намагається викликати?"
  • "Код намагається зателефонувати socket. Це має бути дзвонити! Чи є змінна такою socket, на яку я думаю, що вона є?"
  • Я повинен роздрукувати, що таке сокет, і перевірити print socket

На даний момент я імпортую сокет так: з імпорту сокета *
user551717

Я також змінив його на сокет імпорту сокета, і я все одно отримую ту ж помилку.
користувач551717

@user: якщо ви це зробите, print socketви побачите, що ім'я socketє модулем. Він повинен був десь прив’язаний до цього модуля ! Уважно прочитайте свій код, і я впевнений, що ви побачите таку import socketчи іншу , де цього не очікуєте.
Катріель

2
Ой, я розумію. Це socket.socketбуло трохи заплутано. Я просто зробив, import write_to_fileа потім, оскільки метод, який я використовував всередині write_to_file.py, названий, writeToTextFileя просто попростувавwrite_to_file.writeToTextFile
maudulus

9
Варто зазначити, що це не було очевидно принаймні 133 людям, які потребували часу, щоб проголосувати (включаючи і мене), які цього не розуміли. Тепер це очевидно, і наступного разу, коли я дістанусь до своєї панелі інструментів, я знайду цей інструмент, коли модуль повідомляється як "не дзвонить". Початок роботи з новою мовою - найскладніша частина.
jmort253

168

Припустимо, що вміст YourClass.py такий:

class YourClass:
    # ......

Якщо ви використовуєте:

from YourClassParentDir import YourClass  # means YourClass.py

Таким чином, я отримав TypeError: 'module' об'єкт не можна викликати, якщо ви потім намагалися використовувати YourClass().

Але, якщо ви використовуєте:

from YourClassParentDir.YourClass import YourClass   # means Class YourClass

або використовувати YourClass.YourClass(), це працює для мене.


2
клас = YourClass.YourClass ()
KunMing Xie

2
Я вирішив цю проблему, використовуючи імпорт yourClass *
Кіт

104

Додайте до головного __init__.pyу YourClassParentDir, наприклад:

from .YourClass import YourClass

Потім у вас буде готовий екземпляр класу, коли ви імпортуєте його в інший сценарій:

from YourClassParentDir import YourClass

5
Чи не повинно бути from .YourClass import YourClass у __init__.pyфайлі?
Ніколя Селлер

28

Ось ще одна готча, яка зайняла деякий час, коли я навіть прочитав ці пости. Я налаштовував сценарій для виклику моїх скриптів бітона python. Я отримував модуль також не дзвонити.

Мій зиг в тому, що я робив наступне:

from mypackage.bin import myscript
...
myscript(...)

коли моєму загу потрібно було зробити наступне:

from mypackage.bin.myscript import myscript
...
myscript(...)

Підсумовуючи, двічі перевірте свій пакет та модуль вкладки.

Що я намагаюся зробити, це мати каталог сценаріїв, який не має розширення * .py, і все ще є модулі 'bin', які знаходяться в mypackage / bin, і вони мають моє * .py розширення. Я новачок в упаковці і намагаюся слідувати стандартам, коли їх інтерпретую. Отже, у мене в корені настройки:

setup.py
scripts/
      script1
mypackage/
   bin/
      script1.py
   subpackage1/
   subpackage_etc/

Якщо це не відповідає стандарту, повідомте мене про це.


22

Схоже, те, що ви зробили, імпортується як socketмодуль import socket. Тому socketмодуль. Вам або потрібно змінити цей рядок на self.serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM), як і будь-яке інше використання socketмодуля, або змінити оператор імпорту на from socket import socket.

Або у вас є import socketпісля from socket import *:

>>> from socket import *
>>> serv = socket(AF_INET,SOCK_STREAM)
>>> import socket
>>> serv = socket(AF_INET,SOCK_STREAM)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
TypeError: 'module' object is not callable

Я імпортував сокет як: з імпорту сокета * Я можу його змінити, але це займе деякий час, тому я неохоче.
користувач551717

@user Ви, мабуть, пізніше десь отримали import socket, який імпортує модуль, що socketперевищує клас socket. Див. Фрагмент коду в редагуванні.
moinudin

3
@user: вам слід змінити це. Причина from <...> import *імпорту - погана, погана, погана - це більш-менш це: зазвичай ви точно знаєте, що знаходиться в глобальному просторі імен, адже це саме те, що ви там помістили. Але коли ви import *, ви заповнюєте цей простір імен усілякими речами, які визначають інші модулі. У цьому випадку незрозуміло, звідки взялася назва socket- це модуль чи щось визначене в цьому модулі? Якщо ви завжди використовуєте import socketабо from socket import socket, у вас ніколи не буде цієї проблеми, оскільки ви можете точно бачити, які назви використовуються.
Катріель

добре. Дякую за пораду. Я щойно звик із багатьох навчальних посібників.
користувач551717

7

Я знаю, що цій темі рік, але справжня проблема у вашому робочому каталозі.

Я вважаю, що робочий каталог є C:\Users\Administrator\Documents\Mibot\oops\. Будь ласка, перевірте наявність файлу, вказаного socket.pyв цьому каталозі. Як тільки ви знайдете, перейменуйте або перемістіть його. При імпорті сокета socket.pyвикористовується поточний каталог замість socket.pyкаталогу Python. Сподіваюся, що це допомогло. :)

Примітка. Ніколи не використовуйте імена файлів з каталогу Python для збереження імені файлу вашої програми; це суперечить вашим програмам.


1
Це, безумовно, варто відзначити. Я просто намагався швидко перевірити розетки, тому просто назвав файл socket.py. Що ж, це викликало саме таке повідомлення про помилку. Ця сторінка привела
Czechnology

0

Під час налаштування точки входу console_scripts у setup.py я виявив, що ця проблема існувала тоді, коли кінцевою точкою був модуль або пакет, а не функція в модулі.

Traceback (most recent call last):
   File "/Users/ubuntu/.virtualenvs/virtualenv/bin/mycli", line 11, in <module>
load_entry_point('my-package', 'console_scripts', 'mycli')()
TypeError: 'module' object is not callable

Наприклад

from setuptools import setup
setup (
# ...
    entry_points = {
        'console_scripts': [mycli=package.module.submodule]
    },
# ...
)

Повинно було

from setuptools import setup
setup (
# ...
    entry_points = {
        'console_scripts': [mycli=package.module.submodule:main]
    },
# ...
)

Так що це стосувалося б функції, що викликається, а не самого модуля. Здається, немає значення, якщо модуль має if __name__ == '__main__':блок. Це не зробить модуль можливим дзвонити.


0

Напевно, ви перемогли вбудовану функцію / змінну або щось інше "модуль", встановивши глобальну змінну "модуль". просто надрукуйте модуль, побачите, що в ньому.


0

перевірити оператори імпорту, оскільки модуль не може викликати. У Python все (включаючи функції, методи, модулі, класи тощо) є об'єктом.


-1

Простий спосіб вирішити цю проблему - експорт PYTHONPATHзмінної середовища. Наприклад, для Python 2.6 в Debian / GNU Linux:

export PYTHONPATH=/usr/lib/python2.6`

В інших операційних системах ви спершу знайдете розташування цього модуля або socket.pyфайлу.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.