如果类型(其他)== str,则覆盖 MyClass 中的“__rmod__”不起作用
Overriding the '__rmod__' in MyClass does not work if type(other) == str
我试图在我的 class 中覆盖 __rmod__
的行为;但是,除非 MyClass
继承自 'str',否则它不起作用。这与 Python Issue 28598 类似,我认为解决该问题的原因是如果我将 subclass 'str' 与 MyClass 一起使用,它将起作用。不过我不想subclass 'str'!
显示问题的示例代码(第 4 个 assertEqual 将失败):
类型错误:在字符串格式化期间并非所有参数都已转换
import unittest
class MyClass:
def __init__(self, value):
self.value = value
def __mod__(self, other):
return self.value % int(other)
def __rmod__(self, other):
return int(other) % self.value
def __add__(self, other):
return self.value + int(other)
def __radd__(self, other):
return self.__add__(other)
class UnitTests(unittest.TestCase):
def test_rmod(self):
self.assertEqual(100, MyClass(50) + "50")
self.assertEqual(100, "50" + MyClass(50))
self.assertEqual(1, MyClass(101) % "10")
self.assertEqual(1, "101" % MyClass(10))
if __name__ == '__main__':
unittest.main()
如果我将 MyClass 更新为 subclass 'str'
class MyClass(str)
测试都会通过。
Python 仅在两种特定情况下调用 MyClass.__rmod__()
:
- 如果左侧操作数拒绝通过 returning
NotImplememted
处理 %
操作,或者没有实现 __mod__
挂钩。
- 如果右侧操作数的类型是左侧操作数类型的子class。
Python 字符串可以在 %
运算符的右侧处理 any 类型的对象,因此第一种情况不适用。 str.__mod__()
如果使用右手操作数由于某种原因不起作用并且将 never return NotImplemented
.
因为你的 class 没有继承自 str
第二种情况也不适用。
其他操作,如 +
确实有效,因为第一种情况适用;字符串只接受其他字符串作为右侧值,因此 return NotImplemented
.
如果你必须拦截 string_value % MyClass()
,恐怕你 唯一的选择 是潜入 class str
。
These functions are only called if the left operand does not support the corresponding operation.
链接到 footnote:
“Does not support” here means that the class has no such method, or the method returns NotImplemented
.
主要文档后面有注释:
If the right operand’s type is a subclass of the left operand’s type and that subclass provides a different implementation of the reflected method for the operation, this method will be called before the left operand’s non-reflected method. This behavior allows subclasses to override their ancestors’ operations.
我试图在我的 class 中覆盖 __rmod__
的行为;但是,除非 MyClass
继承自 'str',否则它不起作用。这与 Python Issue 28598 类似,我认为解决该问题的原因是如果我将 subclass 'str' 与 MyClass 一起使用,它将起作用。不过我不想subclass 'str'!
显示问题的示例代码(第 4 个 assertEqual 将失败):
类型错误:在字符串格式化期间并非所有参数都已转换
import unittest
class MyClass:
def __init__(self, value):
self.value = value
def __mod__(self, other):
return self.value % int(other)
def __rmod__(self, other):
return int(other) % self.value
def __add__(self, other):
return self.value + int(other)
def __radd__(self, other):
return self.__add__(other)
class UnitTests(unittest.TestCase):
def test_rmod(self):
self.assertEqual(100, MyClass(50) + "50")
self.assertEqual(100, "50" + MyClass(50))
self.assertEqual(1, MyClass(101) % "10")
self.assertEqual(1, "101" % MyClass(10))
if __name__ == '__main__':
unittest.main()
如果我将 MyClass 更新为 subclass 'str'
class MyClass(str)
测试都会通过。
Python 仅在两种特定情况下调用 MyClass.__rmod__()
:
- 如果左侧操作数拒绝通过 returning
NotImplememted
处理%
操作,或者没有实现__mod__
挂钩。 - 如果右侧操作数的类型是左侧操作数类型的子class。
Python 字符串可以在 %
运算符的右侧处理 any 类型的对象,因此第一种情况不适用。 str.__mod__()
如果使用右手操作数由于某种原因不起作用并且将 never return NotImplemented
.
因为你的 class 没有继承自 str
第二种情况也不适用。
其他操作,如 +
确实有效,因为第一种情况适用;字符串只接受其他字符串作为右侧值,因此 return NotImplemented
.
如果你必须拦截 string_value % MyClass()
,恐怕你 唯一的选择 是潜入 class str
。
These functions are only called if the left operand does not support the corresponding operation.
链接到 footnote:
“Does not support” here means that the class has no such method, or the method returns
NotImplemented
.
主要文档后面有注释:
If the right operand’s type is a subclass of the left operand’s type and that subclass provides a different implementation of the reflected method for the operation, this method will be called before the left operand’s non-reflected method. This behavior allows subclasses to override their ancestors’ operations.