python - 如果 type(other) == str 则覆盖 MyClass 中的 '__rmod__' 不起作用
问题描述
我试图覆盖__rmod__
我班级中的行为;但是,除非MyClass
从 'str' 继承,否则它不起作用。这类似于Python 问题 28598,我认为解决该问题的方法是为什么如果我使用 MyClass 子类化 'str' 它将起作用。我不想继承'str'!
显示问题的示例代码(第 4 个 assertEqual 将失败):
TypeError:字符串格式化期间并非所有参数都转换了
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 更新为子类 'str'
class MyClass(str)
测试将全部通过。
解决方案
MyClass.__rmod__()
Python 仅在两种特定情况下调用:
- 如果左侧操作数
%
通过返回拒绝处理操作NotImplememted
,或者没有__mod__
钩子的实现。 - 如果右侧操作数的类型是左侧操作数类型的子类。
Python 字符串可以处理运算符右侧的任何%
类型的对象,因此第一种情况永远不会适用。str.__mod__()
如果使用右手操作数由于某种原因不起作用并且永远不会返回,则实现直接引发异常NotImplemented
。
由于您的类没有从str
第二种情况继承,因此也不适用。
其他操作,例如+
do 工作,因为适用第一种情况;strings 只接受其他字符串作为右手值,因此 return NotImplemented
。
如果你必须拦截string_value % MyClass()
,你唯一的选择就是子类str
,恐怕。
另请参阅以下文档__rmod__
:
仅当左操作数不支持相应操作时才调用这些函数。
链接到脚注:
这里的“不支持”是指该类没有该方法,或者该方法返回
NotImplemented
。
主要文档如下:
如果右操作数的类型是左操作数类型的子类,并且该子类为操作提供了反射方法的不同实现,则此方法将在左操作数的非反射方法之前调用。此行为允许子类覆盖其祖先的操作。
推荐阅读
- flutter - Flutter 在 null 上调用了 getter 'value'。/ 接收方:null / 尝试调用:值
- python - “sklearn.datasets”没有属性“samples_generator”
- c# - 如何在 C# 中获得虚拟机操作系统?
- python - 获取 ValueError:为 GitHub 包解压的值太多
- db2 - sqlcode -117 - ibm 大型机
- php - 在 phpword 中调用未定义的方法 Phpword::addSection()
- sql - SQL - 递归 CTE 中 UNION 和 UNION ALL 之间差异的说明性示例?
- r - 每两列将函数应用于数据框的列,将该函数的结果存储在列表中,然后将该列表作为列插入
- spring - Spring 验证器未检测到错误
- html - 选择列表中类的最后一个元素