Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python中命名空间包的相对位置和内容>;=3.3_Python_Python 3.x_Python Packaging_Namespace Package - Fatal编程技术网

Python中命名空间包的相对位置和内容>;=3.3

Python中命名空间包的相对位置和内容>;=3.3,python,python-3.x,python-packaging,namespace-package,Python,Python 3.x,Python Packaging,Namespace Package,我阅读了文档和一些stackoverflow帖子,但没有找到一个明确的答案来回答我的疑问 我想我理解名称空间包的用途 我只对Python>=3.3和隐式名称空间包感兴趣——没有\uuuu init\uuuu.py的文件夹 问题 名称空间包是否应该只包含其他包,或者模块(即.py文件)也是“允许的” 名称空间包应该仅用作“容器”包,还是也可以包含在常规包中 如果名称空间包仅作为容器,我想我可以声明,每当我有一个真正的包文件夹时,它包含python模块的所有子文件夹也应该有\uuu init\u

我阅读了文档和一些stackoverflow帖子,但没有找到一个明确的答案来回答我的疑问

我想我理解名称空间包的用途

我只对Python>=3.3和隐式名称空间包感兴趣——没有
\uuuu init\uuuu.py
的文件夹

问题
  • 名称空间包是否应该只包含其他包,或者模块(即
    .py
    文件)也是“允许的”

  • 名称空间包应该仅用作“容器”包,还是也可以包含在常规包中

  • 如果名称空间包仅作为容器,我想我可以声明,每当我有一个真正的包文件夹时,它包含python模块的所有子文件夹也应该有
    \uuu init\uuuuuuuuuupy

  • #这很好
    ns_包/
    +--real_软件包/
    +--_uuinit.py__
    #这个怎么样?
    real_软件包/
    +--_u init.py__#我将其用于文档,并希望强制目录成为一个真正的包
    +--ns_package/#我只想避免使用空的uu init_uuu.py
    +--amodule.py
    
    我怀疑名称空间包仅作为容器才有意义,因为在另一种情况下,我将无法使用不同路径中的其他内容扩展名称空间,因为父级是必须在文件系统的单个点中定义的真实包。因此,我无法获得名称空间包的主要优势

    上下文 我这样问是因为在运行和导入模块(从项目的根)时,在常规包中使用隐式名称空间包的情况非常好。然而,它需要对安装脚本进行一些调整,我想知道我是否首先做了一些有缺陷的事情


    注意:我尝试使用隐式名称空间包主要不是因为我想利用它们的特性,而是因为我讨厌空的
    \uuuu init\uuuuu.py
    文件。我最初认为Python3.3最终摆脱了这个问题,包不再需要
    \uuuu init\uuuu.py
    ,但它似乎并没有那么简单…

    首先:您使用名称空间包的动机是有缺陷的。空的
    \uuuu init\uuuu.py
    文件没有问题;它们现在可能是空的,但以后可以用内容填充。即使他们一直空着也不会引起任何麻烦

    话虽如此,从技术上讲,将名称空间包放在常规包中并没有错。当执行表单导入时,
    import a.b.c
    将分别解析每个组件,
    b
    可以是位于常规包
    a
    中的命名空间包。考虑下面的目录布局:

    .
    └── a
        ├── b
        │   └── c.py
        └── __init__.py
    
    .
    ├── dir1
    │   └── parent
    │       ├── child
    │       │   ├── one.py
    │       ├── __init__.py
    ├── dir2
    │   └── parent
    │       ├── child
    │       │   └── two.py
    │       └── __init__.py
    └── main.py
    
    .
    └── a
        ├── b
        │   ├── c
        │   │   └── three.py
        │   └── two.py
        └── one.py
    
    然后可以导入模块
    c

    >>> import a.b.c
    >>> a
    <module 'a' from '/tmp/a/__init__.py'>
    >>> a.b
    <module 'a.b' (namespace)>
    >>> a.b.c
    <module 'a.b.c' from '/tmp/a/b/c.py'>
    
    有两个命名空间包
    dir1/parent/child
    dir2/parent/child
    。但是,您只能使用其中一个,因为常规包
    dir1/parent
    阻止访问另一个。让我们为
    main.py
    尝试以下内容:

    导入系统 扩展(('dir1','dir1')) 导入parent.child.one#这很有效 打印(系统模块['parent']) 打印(系统模块['parent.child']) 打印(系统模块['parent.child.one']) 导入parent.child.two#此操作失败 我们将得到以下输出:

    <module 'parent' from 'dir1/parent/__init__.py'>
    <module 'parent.child' (namespace)>
    <module 'parent.child.one' from 'dir1/parent/child/one.py'>
    Traceback (most recent call last):
      File "main.py", line 11, in <module>
        import parent.child.two
    ModuleNotFoundError: No module named 'parent.child.two'
    
    您可以导入任何命名空间包中的任何模块:

    >>> import a.one
    >>> import a.b.two
    >>> import a.b.c.three
    >>> a.b.c
    <module 'a.b.c' (namespace)>
    
    >导入一个
    >>>进口a.b.2
    >>>进口a.b.c.3
    >>>a.b.c
    
    2)如上所述,您可以将名称空间包放在常规包中,但这没有多大意义,因为它阻止了它们的预期用途

    3)这在很大程度上取决于你所说的“应该”是什么意思。从技术上讲,
    \uuuuu init\uuuuu.py
    不是必需的,但它确实很有意义


    正如一开始所指出的,
    \uuuu init\uuuuu.py
    文件的用途不仅仅是指示常规python包,而且它们通常也会被内容填充。如果没有,这没什么好担心的。

    谢谢你的回答。我知道empty
    \uuuu init\uuuu.py
    是完全无害的,在文件系统中看到它们会让我感到不安,但这不是一个技术参数:)。1) 很好,这就是我自己已经在做的。我只是在文档中没有直接在名称空间包中看到模块的示例,所以我想知道。2) 我明白,这正是我所怀疑的(见我原来的问题);我在找一份确认书:)。3) 因为2),所以我总是将
    \uuuu init\uuu
    放在真实软件包的子文件夹中,以避免混淆。