使用getattr
在模組中動態實現類似類的行為在某些情況下,可能需要模仿__getattr__ 對類別的行為,但對整個模組的行為。這允許動態創建類別實例並根據模組上的屬性查找呼叫其方法。
但是,嘗試直接在模組上定義 __getattr__ 方法面臨兩個障礙:
基於包裝的解決方案
一種方法是圍繞模組創建一個包裝器。 Sys.modules 能夠容忍不同的物件類型,因此我們可以將模組包裝在一個類別中並將其指派給 sys.modules[__name__]。這允許動態行為而無需修改模組本身。然而,這種技術僅適用於模組級存取。
Guido van Rossum 的 Hack
Guido van Rossum 建議的另一個解決方案涉及替換 sys.path 中的實際模組。具有模組內定義的類別實例的模組。導入機制執行最後的替換步驟,從而實現此駭客攻擊。以下範例示範了這種方法:
<code class="python"># module foo.py import sys class Foo: def funct1(self, *args): <code block> def funct2(self, *args): <code block> sys.modules[__name__] = Foo()</code>
現在,可以透過 Foo 的實例存取模組中定義的函數。
注意事項
使用這些技術時,在 sys.modules 分配後可能無法存取其他模組元素。在替換類別中定義所有必要的功能,以避免遺失模組內容。
__all__ 屬性
使用 from module import * 時,在替換類別中定義 __all__ 來處理此問題導入聲明的類型。省略 __all__ 中的 __module__ 和 __qualname__ 等屬性。
以上是如何在 Python 模組中模仿類別行為?的詳細內容。更多資訊請關注PHP中文網其他相關文章!