假设我有一个列表l
。 l.__rmul__(self, other)
是在什么情况下调用的?
我基本上理解了文档,但我也想看一个例子来毫无疑问地阐明它的用法。
最佳答案
当 Python 尝试将两个对象相乘时,它首先会尝试调用左侧对象的 __mul__()
方法。如果左侧对象没有 __mul__()
方法(或该方法返回 NotImplemented
,表明它不适用于所讨论的右侧操作数),则 Python想知道正确的对象是否可以进行乘法运算。如果右边的操作数和左边的类型相同,Python 知道它不能,因为如果左边的对象做不到,另一个相同类型的对象肯定也做不到。
如果这两个对象是不同的类型,Python 认为值得一试。但是,它需要某种方式告诉正确的对象它是操作中的正确对象,以防操作不是可交换的。 (当然,乘法是,但并非所有运算符都是,并且在任何情况下 *
并不总是用于乘法!)所以它调用 __rmul__()
而不是 __mul__()
.
例如,考虑以下两个语句:
print "nom" * 3
print 3 * "nom"
在第一种情况下,Python 调用字符串的 __mul__()
方法。字符串知道如何将自己乘以一个整数,所以一切都很好。在第二种情况下,整数不知道如何将自己与字符串相乘,所以它的 __mul__()
返回 NotImplemented
和字符串的 __rmul__()
被调用。它知道该怎么做,你得到的结果和第一种情况一样。
现在我们可以看到 __rmul__()
允许 所有 字符串的特殊乘法行为包含在 str
类中,这样其他类型(例如整数)不需要知道任何关于字符串的信息就可以乘以它们。一百年后(假设 Python 仍在使用中)你将能够定义一个新类型,它可以按任意顺序乘以整数,即使 int
类对此一无所知一个多世纪以来。
顺便说一下,字符串类的 __mul__()
在某些 Python 版本中存在错误。如果它不知道如何将自己与对象相乘,它会引发 TypeError
而不是返回 NotImplemented
。这意味着即使用户定义的类型具有 __rmul__()
方法,您也不能将字符串与用户定义的类型相乘,因为字符串永远不会让它有机会。用户定义的类型必须先出现(例如 Foo() * 'bar'
而不是 'bar' * Foo()
)所以它的 __mul__()
被调用。他们似乎已经在 Python 2.7 中修复了这个问题(我也在 Python 3.2 中对其进行了测试),但是 Python 2.6.6 有这个错误。
关于python - 在什么情况下调用__rmul__?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5181320/