python namespace package,python命名空间与软件包:将软件包设为默认命名空间

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

pypackage

├── pypackage

| |

│ ├── bin

| | ├── __init__.py

| | └── pypackage.py

| |

| └── core

| ├── __init__.py

| └── pypackage.py

|

├── tests

├── README.md

└── setup.py

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

from pypackage.core import pypackage

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',

]

},

...

)

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

into this:

import 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.

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 *

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.

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).

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.

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.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值