[英]Is it possible to arrange Python classes/functions into package namespaces, avoiding the module namespace?
讓我們說我的文件結構如下:
.
├── 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
文件中導入)並不好 - 我願意接受任何允許我使用像abClassB1
這樣的名字的abClassB1
,但是在某種形式下保持類似組織在文件夾/文件級別。
你有一個好主意,但你忽略了Python所構建的功能。
Python包是以某種方式相關的模塊的集合。
Python模塊是一個單獨的文件,它包含一組一起工作的類和/或函數。
每個文件不應該有類或函數。 那不是好設計。
試圖搞亂導入系統使abClassB1
引用a/b/ClassB1
文件中的a/b/ClassB1
類是混亂的業務。 這不是導致錯誤的直接原因,但它引入了許多其他復雜情況,並且通常難以解決問題。
我建議至少命名類和文件不同的東西,比如_ClassB1.py
文件和ClassB1
類,這樣你就可以單獨引用類和模塊而不會產生歧義。 這很重要。
在其中點a/b/ClassB1.py
試圖指abClassB0
,對於模塊對象ab
模塊並未實際分配給b
的屬性a
模塊對象。 只有在__init__.py
for ab
完成執行后才會發生這種情況,並且__init__.py
仍在繼續。 在ab
屬性分配發生之前,您不能引用ab
。
除了屬性賦值問題之外, ClassB1.py
還假設abClassB0
是類而不是模塊,這意味着它假設from .ClassB0 import ClassB0
出現在from .ClassB1 import ClassB1
之前__init__.py
from .ClassB1 import ClassB1
。 這引入了導入排序要求,如果ab
問題沒有首先發生,則會導致其他令人討厭的頭痛。
要解決此問題,您可以使用相對導入來訪問兄弟模塊及其內容,而無需嘗試訪問ab
屬性。 不幸的是,這會使你的結構變得更加混亂,因為它的含義就像from . import ClassB0
在ClassB1.py
from . import ClassB0
取決於__init__.py
是否已執行相同的導入。 如果您將文件名更改為與類名不沖突,則事情就會變得更加混亂:
# _ClassB1.py
from ._ClassB0 import ClassB0
class ClassB1(ClassB0):
...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.