2

我正在尝试通过查看流行库中的代码来了解有关 Python 的更多信息。我修改的第一个库是python-requestsKenneth Reitz 的。

我所做的很简单git clone <request_repo_url_from_github>,现在我正在检查代码。

我正在__init__.py浏览requests/packages.

我有几个问题要问:

  1. 为什么__init__.py里面requests/packages,直接下面应该没有__init__.py文件requests?或者它很简单,因为这是一个从 github 直接克隆和卸载的包,就像这样?

  2. 第二个问题是指下面的上面的代码。我想知道的是究竟NullHandler做了什么?我在这里查看了文档,拥有一个“无操作”处理程序意味着什么。图书馆开发人员将在哪里使用此处理程序?我的意思是,它有什么特别之处?


import logging
try:  # Python 2.7+
    from logging import NullHandler
except ImportError:
    class NullHandler(logging.Handler):
        def emit(self, record):
            pass
4

2 回答 2

3

据我记得requests,该packages目录包含作者决定捆绑的其他依赖项的镜像,requests而不是作为依赖项添加。就我个人而言,我会简单地使它们成为依赖关系,并在必要时引用特定版本,但我确信它们有其捆绑方法的原因。在任何情况下,它都包含一个__init__.py,因此代码可以将其视为一个模块并执行以下操作:

import requests.packages.urllib3

如果您查看requestsGithub 上的目录,您会发现该目录中也确实有一个__init__.py。如果你想有一个包的层次结构,你需要在每个级别都有这样的文件,尽管在最简单的情况下它可以是一个空文件。

如果您不放置__init__.py在目录中,Python 不会将其识别为包 - 这是为了防止意外包含来自您不希望的位置的模块。你可以想象一个目录可以被命名为与其他地方的包相同的任何数量的方式,sys.path并导致无数的混乱,但由于其中不会有一个__init__.py,它会被 Python 忽略。

要回答您的第二个问题,这NullHandler是因为出于某种原因方便使用日志记录处理程序但您实际上不想进行任何日志记录的情况。如果您使用的是执行日志记录的库,则可以使用它,但在您的情况下,您实际上并不想记录任何内容 - 您安装 aNullHandler以丢弃这些日志记录消息,因为它比更改更容易(并且更好的做法)他们的库来删除日志记录代码。

在该示例中,我想您可以添加一个替代日志记录并简单地设置日志记录级别,以便实际不生成任何消息,但可以说只使用 a 更容易NullHandler

于 2013-07-16T10:07:59.663 回答
1
  1. 在目录中有一个__init__.py文件会将那个目录变成一个 Python 包。它也不会将子目录转换为包。如果您查看源代码树,您会看到它看起来像这样(删除了不相关的文件)

    requests/
    |
    |-- __init__.py
    |-- packages/
        |
        |-- __init__.py
        |-- charade/
        |   |
        |   |-- __init__.py
        |-- urllib3/
            |
            |-- __init__.py
    

    这定义了一个顶级包 ,requests以及子包requests.packages,requests.packages.charaderequests.packages.urllib3。定义这些包对于使它们可正确导入是必要的。

    直接回答你问的问题,直接下一个__init__.py文件requests/。整棵树中不止一个。

  2. NullHandler什么都不做。它已经到位logging,即使用户没有配置任何记录器,也可以无条件地使用对库的调用。基本上,所有连接到日志库的记录器都会在urllib3尝试记录任何内容时被调用。如果没有附加记录器,则记录库会发出警告。这些很糟糕,因此这是一种解决方法,可以使库代码更简单,而无需强制登录。

于 2013-07-16T10:07:03.353 回答