【问题标题】:python logging __name__ and packagingpython记录__name__和包装
【发布时间】:2018-10-22 06:18:44
【问题描述】:

official python logging documentation 是这样说的:

名称可能是一个以句点分隔的层次值,例如 foo.bar.baz (尽管它也可能只是简单的 foo,例如)。 层次列表中更靠后的记录器是 列表中较高的记录器。例如,给定一个具有名称的记录器 foo 中,名称为 foo.bar、foo.bar.baz 和 foo.bam 的记录器是 foo 的所有后代。记录器名称层次结构类似于 Python包层次结构,如果你组织你的 使用推荐的结构基于每个模块的记录器 logging.getLogger(__name__)。那是因为在一个模块中, __name__ 是 Python 包命名空间中的模块名称。

但我发现最后一句话并不完全正确。 __name__ 的值似乎取决于模块的导入方式。下面证明了这一点:

给定两个模块, foo 和 bar 都在包 pkg 中:

这是foo

def showFoosName():
    print __name__

这是酒吧

from pkg import foo
if __name__ == '__main__':
    foo.showFoosName()

运行栏产生

pkg.foo

但是,如果我们将 baz 引入包 pkg 中,它将 foo 简单地作为 foo 导入,这是合法的,因为两者都在同一个包中:

import foo
if __name__ == '__main__':
    foo.showFoosName() 

运行 baz 产生

foo

现在将这个讨论带回到日志记录和日志记录配置,似乎 python 日志记录建议使用__name__ 命名记录器只有在包中的导入使用from pkg import bar 语法编码时才有效。这不是我所期望的。我原以为__name__ 的值与导入方式无关。

【问题讨论】:

  • 如果您从pkg 目录启动baz.py,那么 没有包pkg:在这种情况下pkg 文件夹不是包,但是 sys.path 的根。这就是为什么您不应该在可导入包的文件夹结构中混入可执行脚本的原因之一。
  • @DanielPryden:鉴于报告的运行 bar 的结果,我倾向于认为 pkg 既是一个包 又是一个 sys.path 条目,但是有还有其他可能性,例如bar 实际上不在pkg 中。无论如何,我同意将脚本与包的结构混合是应避免的。

标签: python logging


【解决方案1】:

这是您的导入路径被破坏的症状。您的路径中有pkg 及其包含目录,导致foo.py 对应于两个单独的模块foopkg.foo

很可能,包含pkg 的目录在您的导入路径上,但您正在通过文件名直接运行bar.pybaz.py,导致pkg 本身也在路径上。跑步

python -m pkg.bar

python -m pkg.baz

应该防止pkg被添加到路径中。

这只是您的导入路径可能被弄乱的一种可能方式。我们真的不能说。阅读 Python 导入系统应该会有所帮助; here's one good resource.

【讨论】:

    【解决方案2】:

    Python 包和模块的特点是,与 Python 中的其他所有内容一样,它们是动态的。每个模块的 __name__ 取决于它相对于 Python 根路径的位置(在 sys.path 上)。因此,如果您有一个名为pkg 的文件夹,即使它包含__init__.py,如果它直接位于sys.path 上,它实际上也不是一个“包”。如果pkg 文件夹直接在sys.path 上(例如,因为您在那里启动了Python 解释器),那么它不是一个包,并且其中的任何.py 文件都是顶级模块,而不是任何内部的模块包裹。因此,如果您在pkg 文件夹中有foo.py,当您从pkg 内部启动Python 解释器时,foo.py 的真实正式名称​​是foo,而不是@987654334 @。

    除非 包含 pkg 的文件夹在 sys.path 上,否则 没有包 pkg -- from pkg import foo 将失败并显示 ImportError .如果pkg 和包含pkg 的文件夹都在sys.path 上,那么您的Python 路径格式错误,并且您有两个单独的可导入模块pkg.foofoo(具有所有全局变量的独立副本!)。

    要解决此类问题,最佳做法是将可执行脚本与可导入模块和包彼此分开。这允许您将所有可导入的模块和包放在一个公共位置(通常,在您的 Python 安装下 site-packages 下),并且您的可执行脚本可以使用全名导入它们,而不管脚本位于何处(通常, /usr/bin/usr/local/bin 之类的地方。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多