当前位置: 首页 > 知识库问答 >
问题:

Python3.3中的包是否不需要_init__u;.py

潘阳舒
2023-03-14

我正在使用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/playdey

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

同样,现在在家里,操场的超级玩家

~ $ 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文件(空的可以工作)在两个ab中,当Python路径指向时,module.py是可导入的>游乐场文件夹?

这似乎与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

~/playway/a~/playway/a/b中使用.\uuu init\uuu.py,工作正常。

共有3个答案

章绪
2023-03-14

如果您的项目中有setup.py,并且您在其中使用find_packages(),则需要在每个目录中有一个__init__. py文件,以便自动找到包。

包只有在包含__init__. py文件时才会被识别

UPD:如果要使用不带\uuu init\uuuuuuupy.py的隐式命名空间包,只需使用find\u namespace\u packages()

文档

章昱
2023-03-14

Python3.3具有隐式名称空间包,允许它在不使用\uuuu init\uuuu.py文件的情况下创建包。

允许隐式名称空间包意味着提供\uuuuu init\uuuuu.py文件的要求可能会被完全删除,并受到影响。

使用\uuuu init\uuuu.py文件的旧方法仍然与Python 2中的方法一样有效。

朱兴运
2023-03-14

@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\u pubsubgoogle\u storage是独立的软件包,但它们共享相同的命名空间google/cloud。为了共享同一名称空间,需要将公共路径的每个目录设置为名称空间包,即google/cloud/。这应该是创建名称空间包的唯一用例,否则就没有必要了。

关键是在googlegoogle/Cloud目录中没有__init__py文件,这样两个目录都可以被解释为命名空间包。在Python 3.3中,在sys.path中,任何名称与正在查找的包名称相匹配的目录都将被识别为该包的贡献模块和子包。因此,当您从google_pubsubgoogle_storage导入时,Python解释器将能够找到它们。

这与常规包不同,常规包是自包含的,这意味着所有部分都位于同一目录层次结构中。当导入包时,Python解释器在sys.path上遇到带有\uuuu init\uuuuu.py文件的子目录时,它将创建一个仅包含该目录中模块的目录包,而不是在该目录外找到所有适当命名的子目录。这对于不想共享名称空间的包来说是非常好的。我强烈建议大家看看Python导入系统中的陷阱,以便更好地了解Python导入在常规和命名空间包中的行为,以及需要注意的\uuuuu init\uuuuuuuuupy陷阱。

  • 如果要创建名称空间包,请仅跳过\uuuuuu init\uuuuuuuuu.py文件。如果您有位于不同位置的不同库,并且希望它们各自为父包(即命名空间包)贡献一个子包,则仅创建命名空间包。

我的回答只是触及常规包和命名空间包如何工作的表面,所以请查看以下资源以获得更多信息:

    PEP 420隐式命名空间包
  • 导入系统-常规包
  • 导入系统-命名空间包
  • Python导入系统中粗心的陷阱
 类似资料:
  • 问题内容: 这样做,即ConcurrentHashMap(所有非retreival操作,等)需要在被包裹块?我知道所有这些操作都是线程安全的,因此这样做有真正的好处/需要吗?使用的唯一操作是和。 问题答案: 不,这样做会失去您的利益。您也可以使用with 或锁定整个表(这是在中包装操作时要执行的操作,因为隐含的监视器是整个对象实例。) 目的是通过允许在表上进行并发读/写而不锁定整个表来提高并发代码

  • 问题内容: 我有一个非常简单的文件: 而且有效。 但是,当我删除元素时,应用程序看不到实体(所有类都带有注释)。 是否有自动扫描类的机制? 问题答案: 你可以使用 该文件定义了一个名为的持久性单元,它使用JTA感知数据源。所述和元素指定管持久类:实体类,可嵌入类和超类映射。该元素指定JAR文件都包含持久化类管理的打包持久单元可见,而该class元素明确命名持久化类管理。 对于,也可以进行设置和配置

  • 问题内容: 我在查看Cristoph Gohlke的python软件包时 ,发现有一个适用于Python 3.3的Virtualenv软件包。 由于标准python库v3.3中有 venv 软件包,我想知道单独安装此软件包是否有优势。 编辑:从这两个软件包的文档中,virtualenv 1.8.2和 venv 我可以说 venv 标准库软件包缺少以下功能: 选项 在setuptools之间选择还是

  • 问题内容: 我想在我的JavaScript代码中包含几个JSON文件,这些文件与JavaScript源文件位于同一目录中。 如果我想包含另一个JavaScript文件,可以直接使用。现在,我正在使用和获取JSON,我认为这是执行此操作的丑陋方法。 是否有类似的要求,使我能够加载JSON文件? 问题答案: 从节点v0.5.x开始,是的,您可以像需要js文件一样要求JSON。 在ES6中:

  • 问题内容: 我需要从该站点下载哪个tar? 我已经尝试过fortrans,但是一直出现此错误(明显地设置了环境变量之后)。 问题答案: 该SciPy的网页用来提供构建和安装说明,但说明现在依靠操作系统二进制分发。要在没有预编译所需库软件包的操作系统上构建SciPy(和NumPy),必须先构建然后静态链接到Fortran库BLAS和LAPACK: 仅执行五个g77 / gfortran / ifor

  • 随着新的工具栏小部件的引入和AppCompat(android.support.v7.widget.Toolbar)版本的推出,是否还需要调用setSupportActionbar(工具栏)?或者调用setSupportActionbar有什么好处吗;现在我们可以设置标题、子标题、导航图标、导航图标单击侦听器(getSupportActionBar()。直接在工具栏上设置DisplayHomeAs