[英]__add__ returns instance of superclass not subclass
當我將一些 class 子類化時,說int
並自定義它的__add__
方法並調用super().__add__(other)
它返回一個int
實例,而不是我的子類。 我可以通過在每個返回int
的方法中的每個super()
調用之前添加type(self)
來解決這個問題,但這似乎太過分了。 必須有更好的方法來做到這一點。 floats
和fractions.Fraction
也會發生同樣的事情。
class A(int):
def __add__(self, other):
return super().__add__(other)
x = A()
print(type(x + 1))
Output:
<class 'int'>
預期 Output:
<class '__main__.A'>
這可以使用描述符來完成。 下面的 class 使用了特殊的方法,當 class 在 class 內部實例化時具有特殊效果。
class SuperCaller:
def __set_name__(self, owner, name):
"""Called when the class is defined. owner is the class that's being
defined. name is the name of the method that's being defined.
"""
method = getattr(super(owner, owner), name)
def call(self, other):
# Note that this self shadows the __set_name__ self. They are two
# different things.
return type(self)(method(self, other))
self._call = call
def __get__(self, instance, owner):
"""instance is an instance of owner."""
return lambda other: self._call(instance, other)
class A(int):
__add__ = SuperCaller()
x = A()
print(type(x + 1))
Output: <class '__main__.A'>
一種方法是創建一個裝飾器,它可以用強制轉換包裝所需的數學運算:
def wrap_math(c):
def wrapped(orig):
return lambda s, o: c(orig(s,o))
maths = ["__add__", "__sub__"]
for op in maths:
func = wrapped(getattr(c, op))
setattr(c, op, func)
return c
@wrap_math
class Special(int)
pass
x = Special(10)
type(x + 10)
完成您要包裝的功能列表,您應該對 go 很好。
super()
function 從父 class 調用方法,在這種情況下是int
。 相反,您應該在__add__
方法中初始化 class:
class A(int):
def __add__(self, number):
return A(self.numerator + number)
x = A(4)
print(type(x + 1))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.