首先我们需要了解下这个文件的功能:
init.py 文件在 Python 中有多种用途,但当我们讨论通过 pip 安装的插件或包时,其主要用途是为了确保:
包的结构完整性:
当你尝试导入一个包(文件夹)时,init.py 确保该文件夹被当作一个包来处理。也就是说,该文件允许你以 import package_name 的方式导入整个包。
初始化代码的执行:
在包的顶级目录中,init.py 可以包含一些初始化代码,这些代码在包首次被导入时执行。
避免命名冲突:
如果你有一个名为 my_module.py 的文件和一个名为 my_module 的包,Python 可能会因为命名冲突而无法正确地导入模块或包。通过添加一个 init.py 文件,你可以明确地告诉 Python 你希望该文件夹被视为一个包。
插件或扩展点:
对于某些插件或扩展系统,init.py 可能用于注册插件或定义扩展点。这样,当你使用这个插件时,相关的扩展或功能可以自动被激活。
所以,当你在 pip 中安装一个包时,通常会看到这个 init.py 文件。这不是必须的,但为了确保包的完整性、可导入性和其他功能,很多开发者选择添加这个文件。
init.py 代码解析:
import urllib3
import chardet
import warnings
from .exceptions import RequestsDependencyWarningdef check_compatibility(urllib3_version, chardet_version):urllib3_version = urllib3_version.split('.')assert urllib3_version != ['dev'] # Verify urllib3 isn't installed from git.# Sometimes, urllib3 only reports its version as 16.1.if len(urllib3_version) == 2:urllib3_version.append('0')# Check urllib3 for compatibility.major, minor, patch = urllib3_version # noqa: F811major, minor, patch = int(major), int(minor), int(patch)# urllib3 >= 1.21.1, <= 1.24assert major == 1assert minor >= 21assert minor <= 24# Check chardet for compatibility.major, minor, patch = chardet_version.split('.')[:3]major, minor, patch = int(major), int(minor), int(patch)# chardet >= 3.0.2, < 3.1.0assert major == 3assert minor < 1assert patch >= 2def _check_cryptography(cryptography_version):# cryptography < 1.3.4try:cryptography_version = list(map(int, cryptography_version.split('.')))except ValueError:returnif cryptography_version < [1, 3, 4]:warning = 'Old version of cryptography ({}) may cause slowdown.'.format(cryptography_version)warnings.warn(warning, RequestsDependencyWarning)# Check imported dependencies for compatibility.
try:check_compatibility(urllib3.__version__, chardet.__version__)
except (AssertionError, ValueError):warnings.warn("urllib3 ({}) or chardet ({}) doesn't match a supported ""version!".format(urllib3.__version__, chardet.__version__),RequestsDependencyWarning)# Attempt to enable urllib3's SNI support, if possible
try:from urllib3.contrib import pyopensslpyopenssl.inject_into_urllib3()# Check cryptography versionfrom cryptography import __version__ as cryptography_version_check_cryptography(cryptography_version)
except ImportError:pass# urllib3's DependencyWarnings should be silenced.
from urllib3.exceptions import DependencyWarning
warnings.simplefilter('ignore', DependencyWarning)from .__version__ import __title__, __description__, __url__, __version__
from .__version__ import __build__, __author__, __author_email__, __license__
from .__version__ import __copyright__, __cake__from . import utils
from . import packages
from .models import Request, Response, PreparedRequest
from .api import request, get, head, post, patch, put, delete, options
from .sessions import session, Session
from .status_codes import codes
from .exceptions import (RequestException, Timeout, URLRequired,TooManyRedirects, HTTPError, ConnectionError,FileModeWarning, ConnectTimeout, ReadTimeout
)# Set default logging handler to avoid "No handler found" warnings.
import logging
from logging import NullHandlerlogging.getLogger(__name__).addHandler(NullHandler())# FileModeWarnings go off per the default.
warnings.simplefilter('default', FileModeWarning, append=True)#这段代码主要做的是检查三个Python库(urllib3, chardet, 和 cryptography)的版本是否满足特定的兼容性要求。以下是详细的解释:
#check_compatibility 函数:
#输入:urllib3_version 和 chardet_version
#这个函数检查两个库的版本号是否满足特定的兼容性要求。
#首先,它确保urllib3不是从git安装的(通过断言assert实现)。
#然后,它检查urllib3的版本号。如果版本号只有两个部分(例如16.1),则添加第三个部分('0')。
#接下来,它检查urllib3的版本是否在1.21.1到1.24之间。
#最后,它检查chardet的版本是否在3.0.2到3.1.0之间。
#_check_cryptography 函数:
#输入:cryptography_version
#这个函数检查cryptography的版本是否小于1.3.4。如果是,则发出警告。
#主执行部分:
#首先,尝试调用check_compatibility函数,传入urllib3和chardet的当前版本作为参数。
#如果在这过程中抛出AssertionError或ValueError异常,则发出警告,指出urllib3或chardet的版本不满足兼容性要求。
#此外,它还尝试启用urllib3的SNI支持(如果可能),并检查cryptography的版本是否满足特定的版本要求。
#简而言之,这段代码的目的是确保所使用的库版本之间是兼容的,并在版本不兼容时给出警告#启用urllib3的SNI支持(如果可能):
#尝试从urllib3.contrib导入pyOpenSSL。
#调用pyOpenSSL.inject_into_urllib3()以尝试启用SNI支持。SNI(Server Name Indication)是一种TLS扩展,允许在一个TCP连接上使用多个SSL/TLS服务器证书。
#如果导入pyOpenSSL失败,则不会执行任何操作。
#静默urllib3的依赖警告:
#从urllib3.exceptions导入DependencyWarning。
#使用warnings.simplefilter('ignore', DependencyWarning)来静默此警告。
#导入版本和元数据:
#从当前包的__version__模块导入各种元数据,如标题、描述、URL、版本等。
#导入其他模块和函数:
#从utils, packages, models, api, sessions, status_codes, 和 exceptions中导入特定的函数、类和模块。
#设置默认的日志处理器:
#为了避免“没有找到处理器”的警告,为当前模块设置一个默认的日志处理器。这是通过添加一个NullHandler实现的。
#处理FileModeWarning警告:
#使用warnings.simplefilter('default', FileModeWarning, append=True)来设置FileModeWarning的默认行为。这意味着对于FileModeWarning,将使用Python的默认警告行为。
#总体来说,这段代码主要是关于导入各种库和模块,并进行一些初始化和配置。它涉及到版本信息、日志处理、警告处理和库之间的依赖关系。
总体来说,当我们引入request库时,init.py文件会做一些初始化的处理,还有一些依赖性的验证,确保当前功能可用。