模塊上的__getattr__如何__getattr__在模塊上實現類的等價?例當調用模塊靜態定義的屬性中不存在的函數時,我希望在該模塊中創建一個類的實例,并在模塊上的屬性查找中使用與失敗相同的名稱調用其上的方法。class A(object):
def salutation(self, accusative):
print "hello", accusative# note this function is intentionally on the module, and not the class abovedef __getattr__(mod, name):
return getattr(A(), name)if __name__ == "__main__":
# i hope here to have my __getattr__ function above invoked, since
# salutation does not exist in the current namespace
salutation("world")這使:matt@stanley:~/Desktop$ python getattrmod.py
Traceback (most recent call last):
File "getattrmod.py", line 9, in <module>
salutation("world")NameError: name 'salutation' is not defined
3 回答

天涯盡頭無女友
TA貢獻1831條經驗 獲得超9個贊
不久之前,Guido宣稱所有關于新式類的特殊方法查找都會繞過__getattr__
和__getattribute__
。Dunder方法曾經工作的模塊-你可以,例如,使用一個模塊作為一個上下文管理器簡單地通過定義__enter__
和__exit__
,這些技巧之前爆發。
最近一些歷史特征已經卷土重來,其中的模塊__getattr__
,所以現在的黑客攻擊(一個模塊sys.modules
在導入時替換為一個類)應該不再需要了。
在Python 3.7+中,您只需使用一種顯而易見的方法。要自定義模塊上的屬性訪問權限,請__getattr__
在模塊級別定義一個函數,該函數應接受一個參數(屬性名稱),并返回計算值或引發AttributeError
:
# my_module.pydef __getattr__(name: str) -> Any: ...
這也允許掛鉤進入“from”導入,即你可以為語句返回動態生成的對象from my_module import whatever
。
在相關的說明中,與模塊getattr一起,您還可以__dir__
在模塊級別定義一個函數來響應dir(my_module)
。有關詳細信息,請參閱PEP 562。

守著一只汪
TA貢獻1872條經驗 獲得超4個贊
這是一個hack,但你可以用一個類包裝模塊:
class Wrapper(object): def __init__(self, wrapped): self.wrapped = wrapped def __getattr__(self, name): # Perform custom logic here try: return getattr(self.wrapped, name) except AttributeError: return 'default' # Some sensible defaultsys.modules[__name__] = Wrapper(sys.modules[__name__])
添加回答
舉報
0/150
提交
取消