类中带有\uuu add \uuu的意外Python行为

2024-04-20 10:05:39 发布

您现在位置:Python中文网/ 问答频道 /正文

我想做一个概率类,比如用于实践的类,所以我构造了一个p类,并希望能够有一个相关的值。我还希望能够添加概率,比如P(“a”)+P(“b”),并让它添加它们的值。这对编写代码来说很好,但是我在测试时遇到了一些奇怪的行为。我只粘贴了下面代码的相关部分[这就是为什么它看起来有点冗长]:

class P:

def __init__(self, event):
    self.event = event
    self.v = 0

def value(self, val):
        """Sets the probability to the value 'val'."""
    self.v = val

def add_stuff(x,y):
    return lambda x,y: x+y

def __add__(self, other):

    if isinstance(other, P):   # if we are adding two P's together.
        return add_stuff(self.v, other.v)

    else:                      # if we are adding a number to our P.
        try: return add_stuff(self.v, other)
        except: raise TypeError(self.type_error_string)



a = P("a")  # Creates the instances.
b = P("b")  #
c = P("c")  #

a.value(0.5)  # Sets the value of a.v to 0.5,
b.value(0.1)  # and so on for b and c.
c.value(0.2)  #

print a.v + b.v == 0.7. # prints True.
print b.v == 0.1        # prints True.
print c.v == 0.2        # prints True.
print b.v + c.v         # prints 0.3.
print type(b.v + c.v)   # prints <float>
print b.v + c.v == 0.3  # prints False (!!).

下面是相关部分。请注意,在测试时,a.v+b.v[以及其他一些值]是正常的,但由于某些原因,b.v+c.v是不正常的。我不知道这里发生了什么。你知道吗


Tags: thetoselfeventaddtruereturnif
2条回答

根据您对add_stuff__add__的定义,看起来您需要:

def __add__(self,other):
    ...
    return add_stuff(self.v, other.v)(self.v,other.v) # add_stuff() returns a function which gets used in the second set of brackets
    ...

除了代码中的一些其他问题外,这个特殊问题还存在于浮点运算的工作方式中:

>>> 0.1 + 0.2
0.30000000000000004
>>> 

考虑阅读这篇伟大的文章:What Every Computer Scientist Should Know About Floating-Point Arithmetic。你知道吗

简而言之:比较float的方法是引入一些容差:abs(b.v - c.v) < Epsilon(您应该适当地定义Epsilon,类似于1e-8)。也可以使用^{}模块。你知道吗

相关问题 更多 >