我正在用 Python 3.9 撰寫一個 API。我將首先提供一個簡化的示例來說明我正在處理的內容,下面的代碼將從設計角度對我嘗試實作的內容進行一些擴展。我剛剛開始涉足更復雜的設計和物件組合的事情,所以我嘗試做的一些事情完全有可能是不可能的或者不是最佳實踐——我很想知道我可以改進什么。
在primary_module.py:
from some_module import do_something
from secondary_module import SecondaryClass
class PrimaryClass:
def __init__(self, param1, param2):
self.attr1 = param1
self._attr2 = do_something(param2)
def primary_method(self):
sec_cls = SecondaryClass(PrimaryClass)
sec_cls.secondary_method()
在secondary_module.py:
class SecondaryClass:
def secondary_method(pri_cls):
print(pri_cls.attr1)
print(pri_cls._attr2)
如您所見,我SecondaryClass定義了一個類 insecondary_module.py并使用它來組成一個名為PrimaryClassin的類primary_module.py。從 API 的角度來看,我希望最終用戶只能直接訪問PrimaryClass并且永遠不要讓他們看到SecondaryClass,即使它正在后臺使用。唯一SecondaryClass需要實體化的時間是在運行PrimaryClass.primary_method()和相關物件時,因此不存在SecondaryClass作為獨立物件運行的情況。但是,在運行此方法時,SecondaryClass需要訪問PrimaryClass. 請記住SecondaryClass(理論上)最終用戶永遠不會直接訪問,允許SecondaryClass查看某些屬性的最佳方法是什么PrimaryClass? 在定義中使用鴨子型別SecondaryClass.secondary_method()來授予它訪問某些屬性(公共和隱藏)的權限是否可以接受PrimaryClass?還是有一些我沒有想到的更好的解決方案?
uj5u.com熱心網友回復:
這并不完全清楚,但我認為這就是你想要的:
class PrimaryClass:
def __init__(self, param1, param2):
self.attr1 = param1
self._attr2 = do_something(param2)
def primary_method(self):
sec_cls = SecondaryClass(self)
sec_cls.secondary_method()
def __private_method(self):
do_something_else()
class SecondaryClass:
def __init__(self, primary):
self.primary = primary
def secondary_method():
print(self.primary.attr1)
print(self.primary._attr2)
SecondaryClass要對 的用戶隱藏primary_module,請使用:
from secondary_module import SecondaryClass as _SecondaryClass
請參閱匯入模塊時隱藏外部模塊(例如關于代碼完成)
uj5u.com熱心網友回復:
如果不了解這些類實際上在做什么,就很難討論這個問題。
也就是說,讓兩個類相互依賴通常不是一個好主意,因為這往往會產生脆弱的代碼:任何一個類的更改都可能破壞兩個類以及依賴于它們中的任何一個的類。
最好通過類建構式(即secondary_method)或作為. 這樣,不依賴于具體的依賴關系,并且明確表示。secondary_method(self._attr2)lambda: __private_method()lambda: self.attr1__init__secondary_methodSecondaryClassPrimaryClasssecondary_methodSecondaryClass
class PrimaryClass:
def __init__(self, param1, param2):
self.attr1 = param1
self._attr2 = do_something(param2)
def primary_method(self):
# E.g. 1: Pass _attr2 via constructor
sec_cls = SecondaryClass(self._attr2)
# E.g. 2 3: Pass attr1 and _attr2 as method parameters
sec_cls.secondary_method(
lambda: self.attr1,
lambda: __private_method(),
)
def __private_method(self):
do_something_else()
class SecondaryClass:
def __init__(self, attr2):
self.attr2 = attr2
def secondary_method(get_attr1, private_callback):
print(self.attr2) # <- _attr2, received from constructor
print(get_attr1()) # <- Getting attr1 at execution time from lambda
private_callback() # <- Calling __private_method
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/429765.html
