Python 3.3+ 中的包不需要 __init__.py

2023-11-26

我正在使用Python 3.5.1。我在这里阅读了文档和包部分:https://docs.python.org/3/tutorial/modules.html#packages

现在,我有以下结构:

/home/wujek/Playground/a/b/module.py

module.py:

class Foo:
    def __init__(self):
        print('initializing Foo')

现在,当在/home/wujek/Playground:

~/Playground $ python3
>>> import a.b.module
>>> a.b.module.Foo()
initializing Foo
<a.b.module.Foo object at 0x100a8f0b8>

同样,现在在home,超级文件夹Playground:

~ $ PYTHONPATH=Playground python3
>>> import a.b.module
>>> a.b.module.Foo()
initializing Foo
<a.b.module.Foo object at 0x10a5fee10>

事实上,我可以做各种各样的事情:

~ $ PYTHONPATH=Playground python3
>>> import a
>>> import a.b
>>> import Playground.a.b

为什么这有效?我虽然需要有__init__.py两个文件(空文件都可以)a and b for module.py当Python路径指向时可导入Playground folder?

这似乎从 Python 2.7 开始发生了变化:

~ $ PYTHONPATH=Playground python
>>> import a
ImportError: No module named a
>>> import a.b
ImportError: No module named a.b
>>> import a.b.module
ImportError: No module named a.b.module

With __init__.py同时~/Playground/a and ~/Playground/a/b效果很好。


Overview

@Mike的答案是正确的,但是太不精确。 Python 3.3+确实支持隐式命名空间包这允许它创建一个包而无需__init__.py文件。这被称为命名空间包相比之下普通套餐其中确实有一个__init__.py文件(空或非空)。

然而,创建一个命名空间包仅应在有需要时才进行。对于大多数用例和开发人员来说,这并不适用,因此您应该坚持使用EMPTY __init__.py文件不管。

命名空间包用例

为了演示两种类型的 python 包之间的区别,让我们看一下以下示例:

google_pubsub/              <- Package 1
    google/                 <- Namespace package (there is no __init__.py)
        cloud/              <- Namespace package (there is no __init__.py)
            pubsub/         <- Regular package (with __init__.py)
                __init__.py <- Required to make the package a regular package
                foo.py

google_storage/             <- Package 2
    google/                 <- Namespace package (there is no __init__.py)
        cloud/              <- Namespace package (there is no __init__.py)
            storage/        <- Regular package (with __init__.py)
                __init__.py <- Required to make the package a regular package
                bar.py

google_pubsub and google_storage是单独的包,但它们共享相同的名称空间google/cloud。为了共享同一个命名空间,需要将公共路径的每个目录都做成一个命名空间包,即google/ and cloud/. 这应该是创建命名空间包的唯一用例,否则就没有必要。

至关重要的是没有__init__py文件在google and google/cloud目录,以便两个目录都可以解释为命名空间包. 在 Python 3.3+ 中的任何目录sys.path名称与正在查找的包名称相匹配的名称将被识别为对该包贡献模块和子包。因此,当您从以下位置导入两者时google_pubsub and google_storage,Python解释器就能找到它们。

这不同于普通套餐它们是独立的,意味着所有部分都位于同一目录层次结构中。当导入一个包并且Python解释器遇到一个子目录时sys.path__init__.py文件,那么它将创建一个仅包含该目录中的模块的单个目录包,而不是查找该目录之外的所有适当命名的子目录。这对于不想共享命名空间的包来说非常好。我强烈推荐看一下Python 导入系统中的陷阱更好地了解 Python 导入如何使用常规包和命名空间包以及什么__init__.py需要提防的陷阱。

Summary

  • 只跳过__init__.py文件,如果你想创建命名空间包。仅当您有驻留在不同位置的不同库并且希望它们各自向父包(即命名空间包)贡献一个子包时,才创建命名空间包。
  • 继续添加空__init__.py到您的目录,因为 99% 的时间您只想创建普通套餐。此外,还有一些 Python 工具,例如mypy and pytest要求为空__init__.py文件来相应地解释代码结构。如果不小心的话,这可能会导致奇怪的错误。

资源

我的回答只触及表面普通套餐 and 命名空间包工作,因此请查看以下资源以获取更多信息:

  • PEP 420 -- 隐式命名空间包
  • 进口系统-普通包裹
  • 导入系统 - 命名空间包
  • Python 导入系统中的陷阱
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python 3.3+ 中的包不需要 __init__.py 的相关文章

随机推荐

  • 如何检查另一个窗口中是否有打开的 URL?

    这是我上一个问题的后续如果窗口尚不存在 则打开一个窗口本质上 我现在保留一个页面已打开的所有窗口引用的列表 并且仅允许它们尚未打开时打开 然后一个潜在的问题引起了我的注意 用户当然有可能关闭原始窗口 然后再次打开它 从而丢失窗口引用列表 是
  • Qt5.6:高DPI支持和OpenGL(OpenSceneGraph)

    我有一个最小的应用程序 它使用QOpenGLWidget集成了 OpenGL 包装库 OpenSceneGraph 我试图弄清楚在处理我使用的 OpenGL 内容时如何正确使用 Qt5 6 对高 DPI 屏幕的支持 My main 函数有以
  • Vite + ESBuild错误:没有为“.node”文件配置加载器:node_modules/fsevents/fsevents.node

    我对 ReactJS 和 Vite 很陌生 我正在编写一些教程 突然开始出现以下错误 我尝试重新安装node modules但没有成功 错误 没有为 node 文件配置加载程序 node modules fsevents fsevents
  • Spring @Transactional 注释不能与自动装配一起使用?

    我的应用程序使用 Spring 自动装配来配置 bean 我刚刚尝试添加 Transactional 预期的代理似乎没有被调用 我希望 PersonalController 使用事务代理包装的 UpdatePublicMapService
  • 从 dotnet Core 2.2.6 更改为 3.0.0 后出现 EF Linq 错误

    我正在尝试将解决方案升级到新的 Core Framework 3 0 0 现在我有一个小问题我不明白 看一下 这个方法在2 2 6中是没有问题的 public async Task
  • Gulp 错误:观看 ENOSPC

    您好 我在运行 gulp watch 时收到此错误 我在用着vueify在 Laravel 项目中 为什么会发生这种情况 这几天一直运行良好 今天就到了 gulp watch 12 56 01 Using gulpfile Document
  • 成功的特定领域语言?您使用哪一款? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心以获得指导 我对领域特定语言的设计和实
  • 在 EAP 6.4.0 中使用 JPA 2.1

    我寻找这个问题的解决方案 到目前为止还没有成功 我们正在将应用程序迁移到 EAP 6 4 0 并且我们的应用程序依赖于 JPA 2 1 然而 JBoss 是一个 Java EE 6 服务器 因此以模块的形式包含 JPA 2 0 我尝试将 J
  • 如何使用 JavaScript 导航到不同的页面

    我目前正在使用以下代码将用户重定向到 C 中的另一个页面 Response Redirect somepage aspx 不过 我想用 JavaScript 来完成此操作 试试下面的代码
  • 如何从SQLite数据库中获取特定月份的数据

    我将数据保存在 SQLite 数据库中 我将日期保存在数据库中作为 DATETIME 数据类型 我只想从 SQLite 数据库中检索特定月份的数据 我尝试使用以下查询来检索数据 但它没有用 它为我提供了数据 但不是特定月份 SELECT c
  • 如何在集群中运行的节点中选举主节点?

    我正在编写一个托管云堆栈 在 EC2 等硬件级云提供商之上 我很快将面临的一个问题是 几个相同的节点如何决定其中哪一个成为主节点 即考虑在 EC2 上运行 5 台服务器 其中一台必须成为主服务器 其他服务器必须成为从服务器 我读到了一个描述
  • 删除 Django 登录表单中电子邮件的区分大小写

    我创建了一个自定义 UserModel 并使用电子邮件作为主要身份验证 ID 而不是用户名 问题是大小写敏感 因为它很重要 电子邮件受保护 电子邮件受保护 作为2个不同的帐户 我需要强制它作为 1 个帐户来处理 忽略它是大写还是小写 这是我
  • 如何在 CI 服务器上的 ASP.NET 网站上使用 NuGet 包

    我有许多 ASP NET Web 表单网站 没有 csproj 文件的网站 我正在尝试找出如何最好地使用它们的 NuGet 包 使用 Visual Studio 2015 时 通过 UI 添加 NuGet 包可以正常工作 站点根目录中有一个
  • 如何获得一个国家的城市边界

    我想从芬兰的 OSM 中提取城市特定数据 我有芬兰的数据 但我只需要 5 个城市的数据 赫尔辛基 埃斯波 万塔 考尼亚宁和 Siuntio 我可以提取赫尔辛基所需的数据 但我需要其余城市的城市边界 这样我可以制作一个多边形 如果我有多边形
  • python 中关键字参数值的命名空间是什么?

    我知道自从我发现 python 以不同的方式对待这个命名空间 def foo l l append 1 print l foo foo foo foo 打印以下内容 1 1 1 1 1 1 1 所以我对它们用作对象初始值设定项持怀疑态度 然
  • 如何获取 StackPanel 中元素的位置?

    假设我有一个 StackPanel 它会动态填充副本 从而更改其中元素的 Y 位置 我在该 StackPanel 中有一个特定元素 我想在 StackPanel 重新定位其所有子元素后找到该元素的 Y 位置 相对于 StackPanel 或
  • Python 2.7 如何解析格式为 2014-05-01 18:10:38-04:00 [重复]

    这个问题在这里已经有答案了 我正在尝试解析这个日期时间字符串 但尚未成功 我该如何获取它 d 2014 05 01 18 10 38 04 00 datetime datetime strptime d Y m d H M S Z Valu
  • 安装 Homebrew Python 后 Python 包位于错误的位置?

    将 Homebrew 的 Python 安装到已安装 Apple Python 的系统上后 列出的最后一个条目sys path使用 Homebrew 的 Python 是 Library Python 2 7 site packages u
  • 将 pandas DateTimeIndex 转换为 Unix 时间?

    将 pandas DateTimeIndex 转换为 Unix 时间 可迭代 的惯用方法是什么 这可能不是要走的路 time mktime t timetuple for t in my data frame index to pydate
  • Python 3.3+ 中的包不需要 __init__.py

    我正在使用Python 3 5 1 我在这里阅读了文档和包部分 https docs python org 3 tutorial modules html packages 现在 我有以下结构 home wujek Playground a