【问题标题】:TypeError: unsupported operand type(s) for *=TypeError: *= 不支持的操作数类型
【发布时间】:2013-05-23 17:17:21
【问题描述】:

我正在通过在线 wikibook 自学 Python,但在其中一个使用重载运算符的示例中遇到了一个令人困惑的错误。根据例子:

class FakeNumber:
    n = 5
    def __add__(A,B):
        return A.n + B.n

c = FakeNumber()
d = FakeNumber()
d.n = 7

c.__imul__ = lambda B: B.n - 6
c *= d
c

应该返回:
1
但我却得到:
TypeError: unsupported operand type(s) for *=: 'FakeNumber' and 'FakeNumber'

我知道你不能将对象相乘,那么c.__imul__ = lambda B: B.n - 6 的意义何在?是否缺少某些东西,或者哪里有不正确的语法?

参考:http://en.wikibooks.org/wiki/Python_Programming/Classes#Operator_Overloading

【问题讨论】:

    标签: python typeerror python-3.3 operand


    【解决方案1】:

    确实,代码在 python 2 中按预期工作,但在 python 3 中没有。python 3 中可能的修复如下:

    class FakeNumber:
        def __init__(self, i):
            self.i = i
    
        def __imul__(self, B):
            self.i = self.i * B.i
            return self
    
    a = FakeNumber(5)
    b = FakeNumber(6)
    
    a *= b
    

    【讨论】:

    • 因此,如果我的操作正确,则在构造 FakeNumber 对象时,它期望在变量中传递。它在哪里存储该变量?
    【解决方案2】:

    该链接解释了 Python 2,并且您正在 Python 3 上尝试。可以详细解释差异(如果您想知道,请查找“旧式类”与“新式类”),但它恢复到:如果在 instance 上定义了像 __imul__ 这样的特殊方法,现在它们总是会被忽略。只有在实例的 class 上定义它们时才会调用它们。所以这条线

    c.__imul__ = lambda B: B.n - 6
    

    不具有定义 += 运算符行为的预期效果:c 只是类 C 的一个实例。

    【讨论】:

    • @Armin_Rigo 我不太擅长 lambda;我会写什么来解决这个问题?
    • 查看@Teisman 的答案,一般不要使用 lambdas。实际上,我不知道他们为什么在教材中使用 lambda。
    猜你喜欢
    • 2020-02-29
    • 2011-03-08
    • 2016-11-28
    • 1970-01-01
    • 2018-04-27
    • 2012-12-26
    • 1970-01-01
    • 2021-05-23
    相关资源
    最近更新 更多