在socket.py文件中,我看到“import _socket”语句后紧跟“from _socket import *”。什么目的?

时间:2017-07-19 04:02:59

标签: python

# from cpython's socket.py
import _socket
from _socket import *

如果你不希望你的当前模块暴露在_socket文件中的所有内容中,我会得到它,你坚持前者 - 否则后者是要走的路。但是,通过这种方式结合两种方式,你究竟取得了什么成果呢?

2 个答案:

答案 0 :(得分:2)

在这种情况下,两个导入都用于"覆盖"具有一些扩展行为的基本模块。

a link to the source at the current revision - python / cpython(socket.py)

用几句话来证明这一点:

getaddrinfo函数希望扩充_socket.getaddrinfo函数,但它必须调用基本实现,因此基本上有两个选项:

  1. from _socket import getattrinfo as getaddrinfo_real并使用getaddrinfo_real
  2. import _socket并直接引用_socket.getaddrinfo
  3. 这个模块做第二个。其余符号(除了class socket(_socket.socket):之外的其他符号)只是从_socket模块继承而来。

    请注意_socket模块is implemented in C - 这些C函数的公共接口位于socket模块中。如果更容易,或者如果它不是性能关键,或者没有任何需要访问的低级对象,可以选择在python中实现部分功能。

    我上面链接的一小段代码:

    def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0):
    
        # (Anthony Sottile): snipped for brevity
    
        # We override this function since we want to translate the numeric family
        # and socket type values to enum constants.
        addrlist = []
        for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
            af, socktype, proto, canonname, sa = res
            addrlist.append((_intenum_converter(af, AddressFamily),
                             _intenum_converter(socktype, SocketKind),
                             proto, canonname, sa))
        return addrlist
    

答案 1 :(得分:0)

扩展我上面的评论,考虑一个名为module.py的模块,如下所示:

#!/usr/bin/env python

import submodule1
from submodule1 import *
import submodule2
from submodule2 import *
import submodule3
from submodule3 import *

这相对和绝对地引入了所有三个子模块的命名空间。因此,我们可以通过以下两种方式之一在function1中引用submodule1

submodule1.function1()
function1()

前一种情况是Pythonic方式,并且是function1中应该调用module.py的方式。但是,作为一个模块,module.py可能由多个文件组成,以便于阅读(分组);但每个子模块实际上都是用作module.py API的一部分。