python - 是否可以将 Python 类/函数排列到包命名空间中,从而避免模块命名空间?

标签 python

假设我的文件结构如下:

.
├── a
│   ├── b
│   │   ├── ClassB0.py
│   │   ├── ClassB1.py
│   │   ├── functionB.py
│   │   └── __init__.py
│   ├── ClassA0.py
│   ├── ClassA1.py
│   ├── functionA.py
│   └── __init__.py
└── test.py

这个想法是每个文件包含一个类或一个函数 - 例如 ClassB0.pyclass ClassB0: ...functionA.pydef functionA(): ... 。但是,我希望能够使用前缀访问这些类/函数,但仅限于与文件夹相关的前缀。因此,我希望能够在该树中的任何文件中执行类似的操作(假设 Python 始终在顶级文件夹中启动):

a.b.functionB()
a.b.ClassB1()
a.ClassA1()
a.functionA()

我想避免使用文件夹和文件的前缀:

a.b.functionB.functionB()
a.b.ClassB1.ClassB1()
a.ClassA1.ClassA1()
a.functionA.functionA()

我尝试通过将以下代码放入 __init__.py 中来做到这一点文件:

from .ClassB0 import ClassB0
from .ClassB1 import ClassB1
from .functionB import functionB

这对于一个“级别”(因此没有 b/ )或非常简单的类来说效果很好。但不同的是ClassB1需求ClassB0这会导致循环依赖,从而破坏整个事情(至少我认为这是我的问题的根本原因)。如果我尝试运行我的脚本,我会收到如下错误:

$ python test.py 
Traceback (most recent call last):
  File "test.py", line 1, in <module>
    import a
  File "/home/freddie/test/testpy/a/__init__.py", line 3, in <module>
    from .functionA import functionA
  File "/home/freddie/test/testpy/a/functionA.py", line 1, in <module>
    import a.b
  File "/home/freddie/test/testpy/a/b/__init__.py", line 2, in <module>
    from .ClassB1 import ClassB1
  File "/home/freddie/test/testpy/a/b/ClassB1.py", line 3, in <module>
    class ClassB1(a.b.ClassB0):
AttributeError: module 'a' has no attribute 'b'

以下是这些文件的完整代码,供引用。

test.py

import a

a.functionA()

a/ClassA0.py

class ClassA0:
    def __init__(self):
        print('ClassA0')

a/ClassA1.py

import a

class ClassA1(a.ClassA0):
    def __init__(self):
        a.ClassA0.__init__(self)
        print('ClassA1')

a/functionA.py

import a.b
import a

def functionA():
    a.ClassA1()
    a.b.functionB()

a/__init__.py

from .ClassA0 import ClassA0
from .ClassA1 import ClassA1
from .functionA import functionA

a/b/ClassB0.py

class ClassB0:
    def __init__(self):
        print('ClassB0')

a/b/ClassB1.py

import a.b

class ClassB1(a.b.ClassB0):
    def __init__(self):
        a.b.ClassB0.__init__(self)
        print('ClassB1')

a/b/functionB.py

import a.b

def functionB():
    a.b.ClassB1()

a/b/__init__.py

from .ClassB0 import ClassB0
from .ClassB1 import ClassB1
from .functionB import functionB

有什么方法可以解决这个问题(无需求助于 Python 导入系统中的低级黑客)?也许我只是太习惯了 C++ 命名空间的工作方式,而这在 Python 中无法完成?

正如我之前所写,我试图拥有一个允许我使用完全限定名称的结构,但没有模块名称,因此只有包名称。我还想避免将所有类/函数重命名为 A_B_ClassB1 ,因为这看起来不太好(;我不是 Python 专家,所以也许我使用的文件结构或我尝试的方法(在 __init__.py 文件中导入)不好 - 我开放任何允许我使用像 a.b.ClassB1 这样的名称的建议,但以某种形式在文件夹/文件级别保持类似的组织。

最佳答案

您有一个好主意,但您忽略了 Python 所围绕的功能。

Python 包是具有某种相关性的模块的集合。

Python 模块是一个单个文件,其中包含一组协同工作的类和/或函数。

每个文件不应该有一个类或函数。这不是好的设计。

关于python - 是否可以将 Python 类/函数排列到包命名空间中,从而避免模块命名空间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43077538/

相关文章:

python - 打印枚举类的所有成员名称

Python 3.6 无法安装到 Linux 下的非标准目录

python - 何时将代码拆分为文件/模块?

python - 从文本中提取表情符号

Python,将一个模块拆分成几个文件

python - 具有不平衡类的 k 折分层交叉验证

python - df.loc 过滤不适用于 None 值

python - 在获取和存储用户输入时如何不覆盖字典的值? (Python)

python - 将多个项目放入 python 队列中

python - 将嵌套字典从 json 转换为以值作为列的数据框