假设我的文件结构如下:
.
├── a
│ ├── b
│ │ ├── ClassB0.py
│ │ ├── ClassB1.py
│ │ ├── functionB.py
│ │ └── __init__.py
│ ├── ClassA0.py
│ ├── ClassA1.py
│ ├── functionA.py
│ └── __init__.py
└── test.py
这个想法是每个文件包含一个类或一个函数 - 例如 ClassB0.py
有class ClassB0: ...
和functionA.py
有def 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/