标签归档:sockets

socket.shutdown与socket.close

问题:socket.shutdown与socket.close

我最近看到了一些看起来像这样的代码(袜子当然是套接字对象):

sock.shutdown(socket.SHUT_RDWR)
sock.close()

在套接字上调用shutdown然后关闭它的目的是什么?如果有所不同,则此套接字用于非阻塞IO。

I recently saw a bit of code that looked like this (with sock being a socket object of course):

sock.shutdown(socket.SHUT_RDWR)
sock.close()

What exactly is the purpose of calling shutdown on the socket and then closing it? If it makes a difference, this socket is being used for non-blocking IO.


回答 0

这是一个解释

一旦不再需要套接字,调用程序就可以通过对套接字描述符应用close子例程来丢弃该套接字。如果在关闭时可靠的传输套接字具有与之关联的数据,则系统将继续尝试进行数据传输。但是,如果仍未交付数据,则系统将丢弃该数据。如果应用程序不使用任何暂挂数据,则可以在关闭套接字之前使用套接字上的shutdown子例程。

Here’s one explanation:

Once a socket is no longer required, the calling program can discard the socket by applying a close subroutine to the socket descriptor. If a reliable delivery socket has data associated with it when a close takes place, the system continues to attempt data transfer. However, if the data is still undelivered, the system discards the data. Should the application program have no use for any pending data, it can use the shutdown subroutine on the socket prior to closing it.


回答 1

调用closeshutdown对基础套接字有两种不同的影响。

首先要指出的是,套接字是基础操作系统中的资源,并且多个进程可以具有同一基础套接字的句柄。

您打电话的时候 close它时,将句柄计数减一,如果句柄计数达到零,则套接字和关联的连接将通过正常的关闭过程(有效地将FIN / EOF发送到对等方)来释放套接字。

这里要注意的是,如果句柄计数没有达到零,因为另一个进程仍然具有套接字的句柄,则连接不会关闭并且套接字不会被释放。

另一方面,调用shutdown读写会关闭基础连接,并向对等方发送FIN / EOF,而不管套接字有多少个进程。但是,它不会取消分配套接字,您仍然需要在事后调用close。

Calling close and shutdown have two different effects on the underlying socket.

The first thing to point out is that the socket is a resource in the underlying OS and multiple processes can have a handle for the same underlying socket.

When you call close it decrements the handle count by one and if the handle count has reached zero then the socket and associated connection goes through the normal close procedure (effectively sending a FIN / EOF to the peer) and the socket is deallocated.

The thing to pay attention to here is that if the handle count does not reach zero because another process still has a handle to the socket then the connection is not closed and the socket is not deallocated.

On the other hand calling shutdown for reading and writing closes the underlying connection and sends a FIN / EOF to the peer regardless of how many processes have handles to the socket. However, it does not deallocate the socket and you still need to call close afterward.


回答 2

关闭和关闭的说明:正常关闭(msdn)

关机(针对您的情况)表示连接的另一端不再有读写套接字的意图。然后关闭释放与套接字关联的所有内存。

忽略关闭可能会导致套接字在操作系统堆栈中徘徊,直到正常关闭连接为止。

在国际海事组织中,“关闭”和“关闭”这两个名称具有误导性,“关闭”和“破坏”将强调它们之间的差异。

Explanation of shutdown and close: Graceful shutdown (msdn)

Shutdown (in your case) indicates to the other end of the connection there is no further intention to read from or write to the socket. Then close frees up any memory associated with the socket.

Omitting shutdown may cause the socket to linger in the OSs stack until the connection has been closed gracefully.

IMO the names ‘shutdown’ and ‘close’ are misleading, ‘close’ and ‘destroy’ would emphasise their differences.


回答 3

在Socket Programming HOWTO(py2 / py3)中已经提到了

断开连接

严格来说,应该先shutdown在套接字上使用close它。该shutdown是在另一端的咨询到插座。根据您传递的参数,它可能表示“ 我不再发送了,但我仍会听 ”,或“ 我不在听,很好的摆脱!”。但是,大多数套接字库都习惯于程序员忽略使用此礼节,通常a close与相同shutdown(); close()。因此,在大多数情况下,不需要显式关闭。

it’s mentioned right in the Socket Programming HOWTO (py2/py3)

Disconnecting

Strictly speaking, you’re supposed to use shutdown on a socket before you close it. The shutdown is an advisory to the socket at the other end. Depending on the argument you pass it, it can mean “I’m not going to send anymore, but I’ll still listen”, or “I’m not listening, good riddance!”. Most socket libraries, however, are so used to programmers neglecting to use this piece of etiquette that normally a close is the same as shutdown(); close(). So in most situations, an explicit shutdown is not needed.


回答 4

上面的代码难道不是错误的吗?

在shutdown调用之后直接执行close调用可能会使内核无论如何都丢弃所有传出缓冲区。

根据 http://blog.netherlabs.nl/articles/2009/01/18/the-ultimate-so_linger-page-or-why-is-my-tcp-not-reliable, 需要在关机和关机之间等待关闭,直到读取返回0。

Isn’t this code above wrong?

The close call directly after the shutdown call might make the kernel discard all outgoing buffers anyway.

According to http://blog.netherlabs.nl/articles/2009/01/18/the-ultimate-so_linger-page-or-why-is-my-tcp-not-reliable one needs to wait between the shutdown and the close until read returns 0.


回答 5

有一些关闭的方式:http : //msdn.microsoft.com/en-us/library/system.net.sockets.socket.shutdown.aspx。* nix是相似的。


回答 6

Shutdown(1),强制套接字no发送更多数据

这在

1-缓冲液冲洗

2-奇怪的错误检测

3-安全防护

让我解释更多,当您将数据从A发送到B时,不保证将其发送到B,仅保证将其发送到A os缓冲区,然后缓冲区又将其发送到B os缓冲区。

因此,通过在A上调用shutdown(1),您将刷新A的缓冲区,如果缓冲区不为空,则会引发错误,即:尚未将数据发送到对等方

但是,这是不可挽回的,因此您可以在完全发送完所有数据之后,并确保至少在对等os缓冲区中执行此操作

Shutdown(1) , forces the socket no to send any more data

This is usefull in

1- Buffer flushing

2- Strange error detection

3- Safe guarding

Let me explain more , when you send a data from A to B , it’s not guaranteed to be sent to B , it’s only guaranteed to be sent to the A os buffer , which in turn sends it to the B os buffer

So by calling shutdown(1) on A , you flush A’s buffer and an error is raised if the buffer is not empty ie: data has not been sent to the peer yet

Howoever this is irrevesable , so you can do that after you completely sent all your data and you want to be sure that it’s atleast at the peer os buffer


如何在python的socket recv方法上设置超时?

问题:如何在python的socket recv方法上设置超时?

我需要在python的socket recv方法上设置超时。怎么做?

I need to set timeout on python’s socket recv method. How to do it?


回答 0

典型的方法是使用select()等待数据可用或超时。仅recv()在实际可用数据时调用。为了安全起见,我们还将套接字设置为非阻塞模式,以确保recv()永远不会无限阻塞。 select()也可以一次在多个插座上等待。

import select

mysocket.setblocking(0)

ready = select.select([mysocket], [], [], timeout_in_seconds)
if ready[0]:
    data = mysocket.recv(4096)

如果您有很多打开的文件描述符,则poll()是更有效的替代方法select()

另一个选择是使用设置套接字上所有操作的超时socket.settimeout(),但是我看到您在另一个答案中明确拒绝了该解决方案。

The typical approach is to use select() to wait until data is available or until the timeout occurs. Only call recv() when data is actually available. To be safe, we also set the socket to non-blocking mode to guarantee that recv() will never block indefinitely. select() can also be used to wait on more than one socket at a time.

import select

mysocket.setblocking(0)

ready = select.select([mysocket], [], [], timeout_in_seconds)
if ready[0]:
    data = mysocket.recv(4096)

If you have a lot of open file descriptors, poll() is a more efficient alternative to select().

Another option is to set a timeout for all operations on the socket using socket.settimeout(), but I see that you’ve explicitly rejected that solution in another answer.


回答 1


回答 2

如前所述都select.select()socket.settimeout()正常工作。

请注意,您可能需要打settimeout两次电话,例如

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(("",0))
sock.listen(1)
# accept can throw socket.timeout
sock.settimeout(5.0)
conn, addr = sock.accept()

# recv can throw socket.timeout
conn.settimeout(5.0)
conn.recv(1024)

As mentioned both select.select() and socket.settimeout() will work.

Note you might need to call settimeout twice for your needs, e.g.

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(("",0))
sock.listen(1)
# accept can throw socket.timeout
sock.settimeout(5.0)
conn, addr = sock.accept()

# recv can throw socket.timeout
conn.settimeout(5.0)
conn.recv(1024)

回答 3

您可以在收到响应之前设置超时,在收到响应之后将其设置回无:

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

sock.settimeout(5.0)
data = sock.recv(1024)
sock.settimeout(None)

You could set timeout before receiving the response and after having received the response set it back to None:

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

sock.settimeout(5.0)
data = sock.recv(1024)
sock.settimeout(None)

回答 4

如果要实现服务器端,则要查找的超时是连接套接字的超时,而不是主套接字的超时。换句话说,连接套接字对象还有另一个超时,这是socket.accept()方法的输出。因此:

sock.listen(1)
connection, client_address = sock.accept()
connection.settimeout(5)    # This is the one that affects recv() method.
connection.gettimeout()     # This should result 5
sock.gettimeout()           # This outputs None when not set previously, if I remember correctly.

如果实现客户端,那将很简单。

sock.connect(server_address)
sock.settimeout(3)

The timeout that you are looking for is the connection socket’s timeout not the primary socket’s, if you implement the server side. In other words, there is another timeout for the connection socket object, which is the output of socket.accept() method. Therefore:

sock.listen(1)
connection, client_address = sock.accept()
connection.settimeout(5)    # This is the one that affects recv() method.
connection.gettimeout()     # This should result 5
sock.gettimeout()           # This outputs None when not set previously, if I remember correctly.

If you implement the client side, it would be simple.

sock.connect(server_address)
sock.settimeout(3)

回答 5

如先前的答复所述,您可以使用类似以下内容的.settimeout() 示例:

import socket

s = socket.socket()

s.settimeout(1) # Sets the socket to timeout after 1 second of no activity

host, port = "somehost", 4444
s.connect((host, port))

s.send("Hello World!\r\n")

try:
    rec = s.recv(100) # try to receive 100 bytes
except socket.timeout: # fail after 1 second of no activity
    print("Didn't receive data! [Timeout]")
finally:
    s.close()

我希望这有帮助!!

As mentioned in previous replies, you can use something like: .settimeout() For example:

import socket

s = socket.socket()

s.settimeout(1) # Sets the socket to timeout after 1 second of no activity

host, port = "somehost", 4444
s.connect((host, port))

s.send("Hello World!\r\n")

try:
    rec = s.recv(100) # try to receive 100 bytes
except socket.timeout: # fail after 1 second of no activity
    print("Didn't receive data! [Timeout]")
finally:
    s.close()

I hope this helps!!


回答 6

您可以使用socket.settimeout()接受代表秒数的整数参数。例如,socket.settimeout(1)将超时设置为1秒

You can use socket.settimeout() which accepts a integer argument representing number of seconds. For example, socket.settimeout(1) will set the timeout to 1 second


回答 7

尝试使用基础C。

timeval = struct.pack('ll', 2, 100)
s.setsockopt(socket.SOL_SOCKET, socket.SO_RCVTIMEO, timeval)

try this it uses the underlying C.

timeval = struct.pack('ll', 2, 100)
s.setsockopt(socket.SOL_SOCKET, socket.SO_RCVTIMEO, timeval)

回答 8

#! /usr/bin/python3.6

# -*- coding: utf-8 -*-
import socket
import time
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
s.settimeout(5)
PORT = 10801

s.bind(('', PORT))
print('Listening for broadcast at ', s.getsockname())
BUFFER_SIZE = 4096
while True:
    try:
        data, address = s.recvfrom(BUFFER_SIZE)
    except socket.timeout:
        print("Didn't receive data! [Timeout 5s]")
        continue
#! /usr/bin/python3.6

# -*- coding: utf-8 -*-
import socket
import time
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
s.settimeout(5)
PORT = 10801

s.bind(('', PORT))
print('Listening for broadcast at ', s.getsockname())
BUFFER_SIZE = 4096
while True:
    try:
        data, address = s.recvfrom(BUFFER_SIZE)
    except socket.timeout:
        print("Didn't receive data! [Timeout 5s]")
        continue

回答 9

喊到:https : //boltons.readthedocs.io/en/latest/socketutils.html

它提供了一个缓冲套接字,它提供了许多非常有用的功能,例如:

.recv_until()    #recv until occurrence of bytes
.recv_closed()   #recv until close
.peek()          #peek at buffer but don't pop values
.settimeout()    #configure timeout (including recv timeout)

Shout out to: https://boltons.readthedocs.io/en/latest/socketutils.html

It provides a buffered socket, this provides a lot of very useful functionality such as:

.recv_until()    #recv until occurrence of bytes
.recv_closed()   #recv until close
.peek()          #peek at buffer but don't pop values
.settimeout()    #configure timeout (including recv timeout)

在localhost上,如何选择空闲端口号?

问题:在localhost上,如何选择空闲端口号?

我正在尝试进行进程间通信,并且由于无法弄清楚如何在Windows下使用命名管道,因此我认为我将使用网络套接字。一切都发生在本地。服务器能够在单独的进程中启动从属服务器,并在某些端口上进行侦听。奴隶完成工作并将结果提交给主人。如何确定哪个端口可用?我假设我无法在端口80或21上收听?

我正在使用Python,如果这样做会减少选择的余地。

谢谢!

I’m trying to play with inter-process communication and since I could not figure out how to use named pipes under Windows I thought I’ll use network sockets. Everything happens locally. The server is able to launch slaves in a separate process and listens on some port. The slaves do their work and submit the result to the master. How do I figure out which port is available? I assume I cannot listen on port 80 or 21?

I’m using Python, if that cuts the choices down.

Thanks!


回答 0

不要绑定到特定端口,也不要绑定到端口0,例如sock.bind(('', 0))。然后,操作系统将为您选择一个可用端口。您可以使用来获得选择的端口sock.getsockname()[1],并将其传递给从站,以便它们可以重新连接。

Do not bind to a specific port, or bind to port 0, e.g. sock.bind(('', 0)). The OS will then pick an available port for you. You can get the port that was chosen using sock.getsockname()[1], and pass it on to the slaves so that they can connect back.


回答 1

为了简要说明上面的解释:

import socket
from contextlib import closing

def find_free_port():
    with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s:
        s.bind(('', 0))
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        return s.getsockname()[1]

For the sake of snippet of what the guys have explained above:

import socket
from contextlib import closing

def find_free_port():
    with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s:
        s.bind(('', 0))
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        return s.getsockname()[1]

回答 2

将套接字绑定到端口0。将选择一个从1024到65535的随机空闲端口。您可以在getsockname()之后紧跟着检索选定的端口bind()

Bind the socket to port 0. A random free port from 1024 to 65535 will be selected. You may retrieve the selected port with getsockname() right after bind().


回答 3

您可以在任何端口上侦听;通常,用户应用程序应侦听端口1024及更高端口(通过65535)。如果您的侦听器数量可变,那么最主要的事情就是为您的应用分配一个范围-例如20000-21000和CATCH EXCEPTIONS。这样,您将知道计算机上端口是否不可用(换句话说,由另一个进程使用)。

但是,就您而言,只要绑定失败时打印错误消息,就可以为侦听器使用单个硬编码端口,这不会有问题。

还要注意,您的大多数套接字(用于从属)不需要显式绑定到特定的端口号-仅需要将等待传入连接的套接字(例如此处的主机)设置为侦听器并绑定到端口。如果在使用套接字之前未为端口指定端口,则操作系统将为该套接字分配可用端口。当主机希望响应从机发送数据时,当侦听器接收数据时,可以访问发送者的地址。

我想您将为此使用UDP?

You can listen on whatever port you want; generally, user applications should listen to ports 1024 and above (through 65535). The main thing if you have a variable number of listeners is to allocate a range to your app – say 20000-21000, and CATCH EXCEPTIONS. That is how you will know if a port is unusable (used by another process, in other words) on your computer.

However, in your case, you shouldn’t have a problem using a single hard-coded port for your listener, as long as you print an error message if the bind fails.

Note also that most of your sockets (for the slaves) do not need to be explicitly bound to specific port numbers – only sockets that wait for incoming connections (like your master here) will need to be made a listener and bound to a port. If a port is not specified for a socket before it is used, the OS will assign a useable port to the socket. When the master wants to respond to a slave that sends it data, the address of the sender is accessible when the listener receives data.

I presume you will be using UDP for this?


回答 4

如果您只需要找到一个空闲端口供以后使用,这是一个类似于先前答案的代码段,但使用socketserver则更短:

import socketserver

with socketserver.TCPServer(("localhost", 0), None) as s:
    free_port = s.server_address[1]

请注意,不能保证端口保持空闲状态,因此您可能需要将此代码段和使用它的代码放入循环中。

If you only need to find a free port for later use, here is a snippet similar to a previous answer, but shorter, using socketserver:

import socketserver

with socketserver.TCPServer(("localhost", 0), None) as s:
    free_port = s.server_address[1]

Note that the port is not guaranteed to remain free, so you may need to put this snippet and the code using it in a loop.


TypeError:“模块”对象不可调用

问题:TypeError:“模块”对象不可调用

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

为什么会出现此错误?我糊涂了。

您需要知道什么才能回答我的问题?

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

Why am I getting this error? I’m confused.

What do you need to know to answer my question?


回答 0

socket是一个包含class的模块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

socket is a module, containing the class socket.

You need to do socket.socket(...) or 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'>

This is what the error message means:
It says module object is not callable, because your code is calling a module object. A module object is the type of thing you get when you import a module. What you were trying to do is to call a class object within the module object that happens to have the same name as the module that contains it.

Here is a way to logically break down this sort of error:

  • module object is not callable. Python is telling me my code trying to call something that cannot be called. What is my code trying to call?”
  • “The code is trying to call on socket. That should be callable! Is the variable socket is what I think it is?`
  • I should print out what socket is and check print socket

回答 1

假设YourClass.py的内容是:

class YourClass:
    # ......

如果您使用:

from YourClassParentDir import YourClass  # means YourClass.py

这样,我得到TypeError:如果您随后尝试使用‘module’对象,则该对象不可调用YourClass()

但是,如果您使用:

from YourClassParentDir.YourClass import YourClass   # means Class YourClass

或使用YourClass.YourClass(),它对我有用。

Assume that the content of YourClass.py is:

class YourClass:
    # ......

If you use:

from YourClassParentDir import YourClass  # means YourClass.py

In this way, I got TypeError: ‘module’ object is not callable if you then tried to use YourClass().

But, if you use:

from YourClassParentDir.YourClass import YourClass   # means Class YourClass

or use YourClass.YourClass(), it works for me.


回答 2

添加到__init__.pyYourClassParentDir中的主目录,例如:

from .YourClass import YourClass

然后,将类导入另一个脚本时,您将准备好该类的实例:

from YourClassParentDir import YourClass

Add to the main __init__.py in YourClassParentDir, e.g.:

from .YourClass import YourClass

Then, you will have an instance of your class ready when you import it into another script:

from YourClassParentDir import YourClass

回答 3

这是另一个陷阱,即使阅读了这些帖子,我也花了一段时间。我正在设置一个脚本来调用我的python bin脚本。我也无法调用该模块。

我的字形是我正在执行以下操作:

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

当我的Zag需要执行以下操作时:

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

总之,请仔细检查您的程序包和模块嵌套。

我正在尝试做的是拥有一个没有* .py扩展名的脚本目录,并且仍然将“ bin”模块放入mypackage / bin中,而这些扩展名具有我的* .py扩展名。我是包装的新手,在解释标准时要遵循这些标准。所以,我在安装根目录下:

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

如果这不符合标准,请告诉我。

Here is another gotcha, that took me awhile to see even after reading these posts. I was setting up a script to call my python bin scripts. I was getting the module not callable too.

My zig was that I was doing the following:

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

when my zag needed to do the following:

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

In summary, double check your package and module nesting.

What I am trying to do is have a scripts directory that does not have the *.py extension, and still have the ‘bin’ modules to be in mypackage/bin and these have my *.py extension. I am new to packaging, and trying to follow the standards as I am interpreting them. So, I have at the setup root:

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

If this is not compliant with standard, please let me know.


回答 4

看来您完成的操作是将socket模块导入为import socket。因此socket是模块。您或者需要将该行更改为self.serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM),以及将该socket模块的所有其他用法更改为1,或者将import语句更改为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

It seems like what you’ve done is imported the socket module as import socket. Therefore socket is the module. You either need to change that line to self.serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM), as well as every other use of the socket module, or change the import statement to from socket import socket.

Or you’ve got an import socket after your 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

回答 5

我知道这个线程已经使用了一年,但是真正的问题出在您的工作目录中。

我相信工作目录是C:\Users\Administrator\Documents\Mibot\oops\。请检查socket.py在此目录中命名的文件。找到它后,对其进行重命名或移动。导入套接字时,socket.py将使用当前目录中的内容,而不是使用socket.pyPython目录中的内容。希望这会有所帮助。:)

注意:切勿使用Python目录中的文件名来保存程序的文件名。它将与您的程序冲突。

I know this thread is a year old, but the real problem is in your working directory.

I believe that the working directory is C:\Users\Administrator\Documents\Mibot\oops\. Please check for the file named socket.py in this directory. Once you find it, rename or move it. When you import socket, socket.py from the current directory is used instead of the socket.py from Python’s directory. Hope this helped. :)

Note: Never use the file names from Python’s directory to save your program’s file name; it will conflict with your program(s).


回答 6

在setup.py中配置console_scripts入口点时,我发现当端点是模块或程序包而不是模块中的函数时,存在此问题。

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__':块,这似乎没有什么区别。这将不会使该模块可调用。

When configuring an console_scripts entrypoint in setup.py I found this issue existed when the endpoint was a module or package rather than a function within the module.

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

For example

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

Should have been

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

So that it would refer to a callable function rather than the module itself. It seems to make no difference if the module has a if __name__ == '__main__': block. This will not make the module callable.


回答 7

我想您已经通过设置全局变量“ module”来覆盖了内置函数/变量或其他“ module”。只需打印模块,看看其中有什么。

I guess you have overridden the builtin function/variable or something else “module” by setting the global variable “module”. just print the module see whats in it.


回答 8

由于模块不可调用,请检查导入语句。在Python中,所有东西(包括函数,方法,模块,类等)都是一个对象。

check the import statements since a module is not callable. In Python, everything (including functions, methods, modules, classes etc.) is an object.


回答 9

解决此问题的一种简单方法是导出PYTHONPATH变量环境。例如,对于Debian / GNU Linux中的Python 2.6:

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

在其他操作系统中,您首先要找到该模块或socket.py文件的位置。

A simple way to solve this problem is export thePYTHONPATH variable enviroment. For example, for Python 2.6 in Debian/GNU Linux:

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

In other operating systems, you would first find the location of this module or the socket.py file.