在Python请求中记录.NullHandler和__init__.py文件位置

时间:2013-07-16 06:59:38

标签: python python-2.7 python-requests

我试图通过查看流行库中的代码来了解有关Python的更多信息。我修改过的第一个图书馆是Kenneth Reitz的python-requests

我所做的只是git clone <request_repo_url_from_github>,现在我正在检查代码。

我正在查看__init__.py中的requests/packages文件。

我有几个问题要问:

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

  2. 第二个问题参考下面的代码。我想知道的是NullHandler到底做了什么?我看了一下文档here,有一个'no-op'处理程序意味着什么。这个处理程序将由库开发人员使用在哪里?我的意思是,它有什么特别之处?


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

2 个答案:

答案 0 :(得分:3)

根据我对requests的记忆,packages目录包含其他依赖项的镜像,作者决定将其与requests捆绑在一起,而不是添加为依赖项。就个人而言,如果有必要,我会简单地将它们作为依赖项,引用特定版本,但我确信它们有捆绑方法的原因。无论如何,它包含__init__.py,因此代码可以将其视为一个模块并执行以下操作:

import requests.packages.urllib3

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

如果你没有将__init__.py放在一个目录中,Python就不会将它识别为一个包 - 这是为了防止意外包含你不喜欢的地方的模块。您可以想象一下目录可以在sys.path上的其他地方命名与包相同的任何方式,并导致无法形容的混淆,但由于其中不会有__init__.py,它会被Python忽略。

要回答第二个问题,NullHandler适用于出于某种原因方便拥有日志处理程序的情况,但实际上并不想进行任何日志记录。如果你使用的是一个执行日志记录的库,你可能会使用它,但在你的情况下,你实际上并不想记录任何东西 - 你安装一个NullHandler来抛弃那些记录消息,因为它更容易(和更好的做法)而不是更改他们的库以去除日志记录代码。

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

答案 1 :(得分:1)

  1. 在目录中有一个__init__.py文件会将该目录转换为Python包。它也将子目录转换为包。如果您查看源树,您会看到它看起来像这样(删除了非相关文件)

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

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

    要直接回答您提出的问题, 直接在__init__.pyrequests/文件。整棵树中不止一个。

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