“自我”和“数字”之间的区别是什么

时间:2019-05-06 20:01:44

标签: python

我有此代码,它不起作用:

class Number:
    def __init__(self, val):
        self.val = val

    def __add__(self, other):
        return self(self.val + other)
x = Number(5)
x += 1
x += 1
print(x.val)

但是当我将self替换为Number时为何起作用?

    def __init__(self, val):
        self.val = val

    def __add__(self, other):
        return Number(self.val + other)
x = Number(5)
x += 1
x += 1
print(x.val)

1 个答案:

答案 0 :(得分:0)

方案1:

class Number:
    def __init__(self, val):
        self.val = val

    def __add__(self, other):
        return self(self.val + other)

x = Number(5)

x是Number类的一个实例,因此在您调用时

x += 1

您调用__add__类的Number,其返回值为self(self.val + other)。由于您在这里告诉python的内容是return self(5 + 1),因此会导致错误。但是,这样做需要在__call__类中定义一个Number方法。这将导致您看到AttributeError: Number instance has no __call__ method错误消息。如果不清楚为什么,请这样想象:

x = Number(5)
x(5 + 1)

方案2:

class Number:
    def __init__(self, val):
        self.val = val

    def __add__(self, other):
        return Number(self.val + other)

x = Number(5)

x是Number类的一个实例,像以前一样。

x += 1

查看您现在返回的内容。您的代码显示return Number(5 + 1),因此x将是Number类的新实例。在某些情况下,这可能正是您想要的,但在这种情况下可能不是。 “新实例”意味着旧的x繁荣了,消失了,返回值为Number(6),这是新初始化的新对象。

x += 1

此处同样,x将是Number类的新实例,并使用(6 + 1)的值进行初始化。因此,这将返回7而不是错误:

print(x.val)

您可能想做的是:

def __add__(self, other):
    self.val += other
    return self

使用此方法,返回值将是调用Number之后的__add__类的相同实例。因此,当您调用x += 1时,x将与您在x = Number(5)上定义的实例相同。如果您致电:

x = Number(5)
x.name = "test"
x += 1
print(x.name)

在这种情况下,xname之后将具有x += 1属性,因为实例在__add__之前和之后都是相同的。在方案2 中,尝试访问x.name会导致AttributeError。