為什么下面的代碼列印error msg而不是ABC\nerror msg?
class CustomException(Exception):
"""ABC"""
def __init__(self, *args):
super().__init__(*args)
self.__str__ = self._wrapper(self.__str__)
def _wrapper(self, f):
def _inner(*args, **kwargs):
return self.__doc__ '\n' f(*args, **kwargs)
return _inner
print(CustomException('error msg'))
uj5u.com熱心網友回復:
暫時忘記 Exception 類。考慮一下:
class A:
def __str__(self):
return 'A'
obj = A()
print(obj)
obj.__str__ = lambda x: 'B'
print(obj)
A.__str__ = lambda x: 'B'
print(obj)
輸出:
A
A # Not B !
B
Dunder 方法的查找在 Python 中是不同的。從檔案:
對于自定義類,特殊方法的隱式呼叫只有在物件型別上定義時才能保證正常作業,而不是在物件的實體字典中。
你想要達到的是:
class CustomException(Exception):
"""ABC"""
def __init__(self, *args):
super().__init__(*args)
def __str__(self):
return self.__doc__ '\n' super().__str__()
print(CustomException('error msg'))
輸出:
ABC
error msg
uj5u.com熱心網友回復:
由特殊方法支持的操作通常顯式地將特殊方法查找為適當的方法,而不僅僅是作為可呼叫的屬性。具體來說,而不是self.__str__解釋器粗略地查看type(self).__str__.__get__(self, type(self))——即要與實體系結的類上的描述符__str__ 。為了覆寫一個特殊的方法,因此有必要覆寫類的描述符而不是實體的屬性。
這可以通過 a) 將特殊方法宣告為處理type(self).__str__部件的槽,以及 b) 分配一個處理__get__(self, type(self))部件的函式。
class CustomException(Exception):
"""ABC"""
__slots__ = ("__str__",) # <<< magic
def __init__(self, *args):
super().__init__(*args)
# vvv self.__str__ is the class' slot
self.__str__ = self._wrapper(super().__str__)
# AAA real __str__ lives on the super class
def _wrapper(self, f):
def _inner(*args, **kwargs):
return self.__doc__ '\n' f(*args, **kwargs)
return _inner
print(CustomException('error msg'))
請注意,由于在這種情況下每個實體的行為都相同,因此建議__str__在實踐中只定義一個新方法。
uj5u.com熱心網友回復:
根據@khelwood在評論中的回復,此代碼按預期作業:
class CustomException(Exception):
"""ABC"""
def __init__(self, *args):
super().__init__(*args)
self.__class__.__str__ = self._wrapper(self.__str__)
def _wrapper(self, f):
def _inner(*args, **kwargs):
return self.__doc__ '\n' f()
return _inner
但我最終得到了這個等價物(@MisterMiyagi):
class CustomException(Exception):
"""ABC"""
def __str__(self):
return self.__doc__ '\n' super().__str__()
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/366163.html
上一篇:類別庫中的C#例外-事件處理程式
