TypeError: 'module' nesnesi çağrılamaz


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

Neden bu hatayı alıyorum? Kafam karıştı.

Soruma cevap vermek için ne bilmeniz gerekiyor?


8
Bir keresinde bu hatayı aldım çünkü hem (global) değişken hem de aynı ada sahip bir fonksiyonum vardı.
remustata

Yanıtlar:


563

socketsınıfı içeren bir modüldür socket.

Yapmanız gereken socket.socket(...)veya 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'>

Hata mesajının anlamı şudur: Kodunuz bir modül nesnesini çağırdığı için
söylüyor . Bir modül nesnesi, bir modülü içe aktardığınızda aldığınız şey türüdür. Yapmaya çalıştığınız şey,module object is not callable , modül nesnesinin içinde, onu içeren modülle aynı ada sahip sınıf nesnesini .

Bu tür bir hatayı mantıksal olarak parçalamanın bir yolu:

  • "module object is not callable . Python bana kodumu çağrılamayan bir şeyi çağırmaya çalışıyor. Kodum ne çağırmaya çalışıyor?"
  • "Kod çağırmaya çalışıyor socket. Bu çağrılabilir olmalı! Değişkendirsocket sanırım öyle mi?` `
  • Soketin ne olduğunu yazdırmalı ve kontrol etmeliyim print socket

Şu anda böyle soket duyuyorum: from socket import *
user551717

Ayrıca soket alma soketinden değiştirdim ve hala aynı hatayı alıyorum.
user551717

@user: yaparsanız print socketadın socketbir modül olduğunu görürsünüz . Bir yere bu modüle bağlı olmalı ! Kodunuzu dikkatlice okuyun ve eminim import socketbeklemediğiniz yerlerde bir veya daha fazlasını göreceksiniz .
Katriel

2
Ohh anladım. socket.socketBiraz kafa karıştırıcı oldu. Basitçe yaptım import write_to_fileve sonra, içinde kullandığım yöntemin write_to_file.pyismini writeToTextFileverdiğim için sadece randwrite_to_file.writeToTextFile
maudulus

9
Bunun, bunu anlamayan (kendim dahil) oy almak için zaman alan en az 133 kişi için açık olmadığını belirtmek gerekir. Şimdi, açıktır ve bir dahaki sefere araç kutuma ulaştığımda, bir modül "çağrılabilir değil" olarak bildirildiğinde bu aracı bulacağım. Yeni bir dile başlamak en zor kısımdır.
jmort253

168

YourClass.py içeriğinin :

class YourClass:
    # ......

Eğer kullanırsan:

from YourClassParentDir import YourClass  # means YourClass.py

Bu şekilde, TypeError: 'module' nesnesini daha sonra kullanmaya çalıştığınızda çağrılamazsınız.YourClass() .

Ancak, kullanırsanız:

from YourClassParentDir.YourClass import YourClass   # means Class YourClass

ya da kullan YourClass.YourClass(), benim için çalışıyor.


2
class = YourClass.YourClass ()
KunMing Xie

2
Sınıfınızı içe aktarma * kullanarak bu sorunu çözdüm
Keith

104

__init__.pyYourClassParentDir içindeki ana öğeye ekleyin, örneğin:

from .YourClass import YourClass

Ardından, başka bir komut dosyasına içe aktardığınızda sınıfınızın bir örneğini hazır hale getireceksiniz:

from YourClassParentDir import YourClass

5
Olması gerekmiyor from .YourClass import YourClass içinde __init__.pydosyanın?
Nicolas Seiller

28

İşte bu yazıları okuduktan sonra bile görmem biraz zaman alan başka bir gotcha. Python bin scriptlerimi çağırmak için bir script ayarlıyordum. Ben de modül çağrılabilir değildi alıyordum.

Zigim, aşağıdakileri yaptığımdı:

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

zag'ım aşağıdakileri yapmak istediğinde:

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

Özetle, paketinizi ve modül yuvalamayı iki kez kontrol edin.

Ne yapmaya çalışıyorum * .py uzantısına sahip olmayan bir komut dosyası dizini var ve hala mypackage / bin içinde 'bin' modülleri var ve bunlar benim * .py uzantısına sahip. Ambalaj konusunda yeniyim ve standartları yorumladığım şekilde takip etmeye çalışıyorum. Yani, kurulum kökünde var:

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

Bu standartla uyumlu değilse, lütfen bana bildirin.


22

Yaptığınız şey socketmodül olarak içe aktarılmış gibi görünüyor import socket. Bu nedenle socketmodül. Bu satırı veya modülün self.serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)diğer tüm kullanımlarını socketdeğiştirmeniz veya içe aktarma ifadesinifrom socket import socket .

Veya bir var import socketsenin after 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

Soketi şu şekilde içe aktardım: soket ithalatından * Değiştirebilirim, ancak biraz zaman alacak, bu yüzden isteksizim.
user551717

@user Muhtemelen daha sonra bir yerde var import socket, bu socketda sınıfı geçersiz kılan modülü içeri aktaracak socket. Düzenleme sırasında kod snippet'ine bakın.
moinudin

3
@ kullanıcı: değiştirmeniz gerekir. from <...> import *İthalatın nedeni kötü, kötü, kötü aşağı yukarı budur: normalde küresel isim alanında tam olarak ne olduğunu bilirsiniz, çünkü tam olarak oraya koyduğunuz şeydir. Ancak siz import *, bu ad alanını diğer modüllerin tanımladığı her türlü şeyle doldurursunuz. Bu durumda, adın nereden socketgeldiği belirsizdir - modül veya bu modülde tanımlanan bir şey mi? Her zamanimport socket veya kullanırsanız from socket import socket, tam olarak hangi adların kullanıldığını görebileceğiniz için bu sorunu asla yaşamayacaksınız.
Katriel

Tamam. Bahşiş için teşekkürler. Bir çok öğreticiden alışkanlık kazandım.
user551717

7

Bu iş parçasının bir yaşında olduğunu biliyorum, ama asıl sorun çalışma dizininizde.

Çalışma dizininin olduğuna inanıyorum C:\Users\Administrator\Documents\Mibot\oops\. Lütfen socket.pybu dizinde adlandırılan dosyayı kontrol edin . Bulduğunuzda, yeniden adlandırın veya taşıyın. Soketi içe aktardığınızda, Python'un dizini socket.pyyerine geçerli dizinden kullanılır socket.py. Umarım bu yardımcı olmuştur. :)

Not: Programınızın dosya adını kaydetmek için asla Python dizinindeki dosya adlarını kullanmayın; programlarınızla çakışacaktır.


1
Bu kesinlikle kayda değer. Sadece soketleri ile hızlı bir kontrol deniyordum, bu yüzden sadece dosyayı adlandırdım socket.py. Bu aynı hata mesajına neden oluyordu. Bu sayfa beni doğru yola koydu: python-notes.curiousefficiency.org/en/latest/python_concepts/…
Çekçe Teknoloji

0

Setup.py içindeki bir console_scripts giriş noktasını yapılandırırken, bu noktanın, modül içindeki bir işlev yerine bir modül veya paket olduğunda mevcut olduğunu gördüm.

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

Örneğin

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

Olması gerekirdi

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

Böylece modülün kendisi yerine çağrılabilir bir işleve atıfta bulunacaktır. Modülün bir if __name__ == '__main__':bloğu varsa fark etmez . Bu, modülü çağrılabilir yapmaz.


0

Küresel değişken "modül" ayarlayarak yerleşik fonksiyon / değişken veya başka bir "modül" geçersiz kılınmış sanırım. sadece modülde ne olduğunu görmek için yazdırın.


0

bir modül çağrılabilir olmadığından içe aktarma ifadelerini kontrol edin. Python'da her şey (işlevler, yöntemler, modüller, sınıflar vb. Dahil) bir nesnedir.


-1

Bu sorunu çözmenin basit bir yolu PYTHONPATHdeğişken ortamı dışa aktarmaktır . Örneğin, Debian / GNU Linux'taki Python 2.6 için:

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

Diğer işletim sistemlerinde, önce bu modülün veya socket.pydosyanın konumunu bulacaksınız .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.