__add__ returns 超类的实例不是子类
__add__ returns instance of superclass not subclass
当我子class一些class时,说int
,并自定义它的__add__
方法并调用super().__add__(other)
它returns一个int
的实例,而不是我的子 class。我可以通过在 returns 和 int
的每个 super()
调用之前添加 type(self)
来解决这个问题,但这似乎过分了。必须有更好的方法来做到这一点。 floats
和 fractions.Fraction
s.
也会发生同样的事情
class A(int):
def __add__(self, other):
return super().__add__(other)
x = A()
print(type(x + 1))
输出:
<class 'int'>
预期输出:
<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)
完成您要包装的函数列表,您应该可以开始了。
super()
函数从父 class 调用方法,在本例中是 int
。相反,您应该在 __add__
方法中初始化 class:
class A(int):
def __add__(self, number):
return A(self.numerator + number)
x = A(4)
print(type(x + 1))
这可以使用 descriptor 来完成。以下 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))
输出:<class '__main__.A'>
当我子class一些class时,说int
,并自定义它的__add__
方法并调用super().__add__(other)
它returns一个int
的实例,而不是我的子 class。我可以通过在 returns 和 int
的每个 super()
调用之前添加 type(self)
来解决这个问题,但这似乎过分了。必须有更好的方法来做到这一点。 floats
和 fractions.Fraction
s.
class A(int):
def __add__(self, other):
return super().__add__(other)
x = A()
print(type(x + 1))
输出:
<class 'int'>
预期输出:
<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)
完成您要包装的函数列表,您应该可以开始了。
super()
函数从父 class 调用方法,在本例中是 int
。相反,您应该在 __add__
方法中初始化 class:
class A(int):
def __add__(self, number):
return A(self.numerator + number)
x = A(4)
print(type(x + 1))
这可以使用 descriptor 来完成。以下 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))
输出:<class '__main__.A'>