python 命名空间 vs 包:使包成为默认命名空间 [英] python namespaces vs packages: making a package the default namespace

查看:70
本文介绍了python 命名空间 vs 包:使包成为默认命名空间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含总体命名空间的项目,其中包含包.这是文件夹结构:

I have a project with an overarching namespace, with packages inside it. Here's the folder structure:

pypackage
├── pypackage             <-- Source code for use in this project.
|   |
│   ├── bin               <-- Module: Cli entry point into pyproject.
|   |   ├── __init__.py
|   |   └── pypackage.py
|   |
|   └── core              <-- Module: Core functionality.
|       ├── __init__.py
|       └── pypackage.py
|
├── tests             
├── README.md         
└── setup.py          

很简单.如果我想导入它,我使用:

Pretty simple. If I want to import it I use:

from pypackage.core import pypackage

而且效果很好,因为我的 setup.py 看起来像这样:

and it works great because my setup.py looks like this:

from setuptools import setup, find_packages
...
NAME = 'pypackage'
setup(
    name=NAME,
    namespace_packages=[NAME],
    packages=[f'{NAME}.{p}' for p in find_packages(where=NAME)],
    entry_points={
        "console_scripts": [
            f'{NAME} = {NAME}.bin.{NAME}:cli',
        ]
    },
    ...
)

但是,我有遗留代码,当它曾经只是一个独立的 python 文件时,它会导入这个 pypackage.像这样:

However, I have legacy code that imports this pypackage when it used to just be a stand alone python file. like this:

import pypackage

那么我该如何制作它才能使命名空间和子包保持相同的结构,但仍以旧方式导入它?我该如何转:

So how do I make it so I can keep the same structure with namespaces and subpackages but still import it the old way? How do I turn this:

from pypackage.core import pypackage

进入这个:

import pypackage

换句话说,当我导入 pypackage 时,我如何将 pypackage.core.pypackage 模块别名为 pypackage代码>到外部项目?

In other words, how do I alias the pypackage.core.pypackage module to be pypackage for when I'm importing pypackage into an external project?

推荐答案

您可以通过导入顶级包来在新包中添加旧"名称.

You would add the 'old' names inside your new package by importing into the top-level package.

pypackage/__init__.py 中作为全局变量导入的名称是 pypackage 包上的属性.利用它来访问旧"位置:

Names imported as globals in pypackage/__init__.py are attributes on the pypackage package. Make use of that to give access to 'legacy' locations:

# add all public names from pypackage.core.pypackage to the top level for
# legacy package use
from .core.pypackage import *

现在任何使用 import pypackage 的代码都可以使用 pypackage.foopypackage.bar 如果实际上这些对象是在 pypackage.core.pypackage 代替.

Now any code that uses import pypackage can use pypackage.foo and pypackage.bar if in reality these objects were defined in pypackage.core.pypackage instead.

现在,因为 pypackage 是一个 setuptools namespace package 你有一个不同的问题;命名空间包可用于安装多个单独的发行版,因此顶级包必须是 empty 或仅包含最小的 __init__.py 文件(命名空间包创建时为空目录需要 Python 3.3).

Now, because pypackage is a setuptools namespace package you have a different problem; namespace packages are there for multiple separate distributions to install into so that top-level package must either be empty or only contain a minimum __init__.py file (namespace packages created with empty directories require Python 3.3).

如果您是使用此命名空间的发行版的唯一发布者,您可以在这里作弊并在您的 core 中使用 single __init__.py 文件 可以使用 pkg-util 的包-style __init__.py 文件 带有我上面使用的附加导入,但是您不得在其他分发包中使用任何 __init__.py 文件 或要求它们都使用完全相同的 __init__.py 内容.协调是关键.

If you are the only publisher of distributions that use this namespace, you can cheat a little here and use a single __init__.py file in your core package that could use pkg-util-style __init__.py file with the additional import I used above, but then you must not use any __init__.py files in other distribution packages or require that they all use the exact same __init__.py content. Coordination is key here.

或者您将不得不使用不同的方法.将 pypackage 保留为遗留的包装器模块,并重命名新的包格式以使用可以位于旧模块旁边的新的、不同的顶级名称.此时,您可以直接将遗留包作为额外的顶级模块包含在您的项目中.

Or you would have to use a different approach. Leave pypackage as a legacy wrapper module, and rename the new package format to use a new, different top-level name that can live next to the old module. At this point you can then just include the legacy package in your project, directly, as an extra top-level module.

这篇关于python 命名空间 vs 包:使包成为默认命名空间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆