[英]python namespaces vs packages: making a package the default namespace
我有一個帶有總體命名空間的項目,其中包含程序包。 這是文件夾結構:
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
很簡單 如果要導入,請使用:
from pypackage.core import pypackage
而且效果很好,因為我的setup.py看起來像這樣:
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
。 像這樣:
import pypackage
那么,如何做到這一點,以便可以與名稱空間和子包保持相同的結構,但仍然可以采用舊方法導入它? 我該如何轉:
from pypackage.core import pypackage
到這個:
import pypackage
換句話說, 我怎么別名pypackage.core.pypackage
模塊被pypackage
當我輸入了pypackage
到外部的項目?
您可以通過導入頂級程序包,在新程序包中添加“舊”名稱。
在pypackage/__init__.py
中作為全局變量導入的名稱是pypackage
軟件包的屬性。 利用它可以訪問“舊版”位置:
# add all public names from pypackage.core.pypackage to the top level for
# legacy package use
from .core.pypackage import *
現在,如果實際上這些對象是在pypackage.core.pypackage
中定義的,則任何使用import pypackage
代碼import pypackage
可以使用pypackage.foo
和pypackage.bar
。
現在,由於pypackage
是setuptools 命名空間包,因此您遇到了另一個問題。 命名空間包可用於安裝多個單獨的發行版,因此頂級包必須為空或僅包含最小的__init__.py
文件(使用空目錄創建的命名空間包需要Python 3.3)。
如果您是使用此名稱空間的發行版的唯一發行商,則可以在此處作弊,並在core
軟件包中使用單個 __init__.py
文件,該文件可以將pkg-util樣式的__init__.py
文件與我上面使用的其他導入配合使用,但是您不得在其他分發程序包中使用任何__init__.py
文件,或要求它們都使用完全相同的__init__.py
內容。 協調是這里的關鍵。
否則您將不得不使用其他方法。 將pypackage
保留為舊包裝模塊,並重命名新的軟件包格式,以使用可以在舊模塊旁邊使用的新的頂級名稱。 此時,您可以將遺留包直接包含在項目中,作為額外的頂層模塊。
如果我使用軟件包,Martin Pieters有一個正確的主意,但是名稱空間軟件包是setuptools的東西。
所以那沒有用。 經過更多的研究,我了解到沒有辦法去做我想做的事情。 因此,如果我真的想這樣做,則必須將所有內容都轉換為常規的包層次結構,而不是名稱空間包,然后使用馬丁的解決方案。
我決定修改舊代碼,而不是以新方式導入它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.