覆盖__eq__并比较两个对象

时间:2016-02-03 19:05:52

标签: python python-3.x object initialization

我有两个独特的温度对象,我需要相互比较,但是,由于对象可以相等但具有不同的单位,我在比较它们时遇到了麻烦。

例如

t1 = Temperature(32.0, 'F')

t2 = Temperature(0.0, 'C')

这两个对象是相同的,但我似乎无法正确实现__eq__来比较它们

这是我尝试过的事情

class Temperature():

    def __init__(self, temp = 0.0, unit = 'C'):
        if float(temp) == str(temp):
            raise ValueError('could not convert string to float: ' + "'" + str(temp) + "'")
        else:
            self.t = float(temp)
        if unit.upper() not in 'CF':
            raise UnitError('Unrecognized temperature unit ' + "'" + str(unit) + "'")
        else:
            self.u = unit.upper()

    def __repr__(self):
        return "Temperature({},'{}')".format(self.t, self.u)

    def __str__(self):
        return str(self.t) + '°' + self.u.upper()

    def __eq__(self, other):
        t1 = Temperature(self.t, self.u)
        t2 = Temperature(other.t, other.u)
        other.convert()

        if t1.t == t2.t and t1.u == t2.u:
            return True
        return False

    def convert(self):
        t = Temperature(self.t, self.u)
        if t.u.upper() == 'C':
            t.t *= 1.8
            t.t += 32
            t.u = 'F'
            return t
        else:
            t.t -= 32
            t.t /= 1.8
            t.u = 'C'
            return t

请注意,我确实有一种方法可以将温度从一个单位转换为另一个单位。同样,我似乎无法弄清楚如何比较这两个对象,当它们处于不同的单位时。

5 个答案:

答案 0 :(得分:1)

我没有仔细看你的转换函数,但假设它正确返回转换温度,那么这应该工作。基本思路是检查单位是否匹配。如果没有,转换另一个并在新的比例上获得它的温度。如果单位匹配,只需比较临时值

{{1}}

答案 1 :(得分:1)

将两者都更改为一种类型并允许浮点错误:

    [HttpGet]
    [Route("Products/{yearId}")]
    public async Task<IEnumerable<Make>> GetProductsYearId(int yearId)
    {
        ....
    }

    [HttpGet]
    [Route("Products/{makeid}")]
    public async Task<Make> GetProductById(int makeid) 
    {
         .....      
    }

你不能正常化一个,因为你不知道哪个是华氏温度或哪个是摄氏温度,你需要假设所有的变化都是可能的,所以只要将任何细胞变为华氏温度就意味着你总是比较一致:

class Temperature():
    def __init__(self, temp=0.0, unit='C'):
        if float(temp) == str(temp):
            raise ValueError('could not convert string to float: ' + "'" + str(temp) + "'")
        else:
            self.t = float(temp)
        if unit.upper() not in 'CF':
            raise Exception
        else:
            self.u = unit.upper()

    def __repr__(self):
        return "Temperature({},'{}')".format(self.t, self.u)

    def __str__(self):
        return str(self.t) + '°' + self.u.upper()

    def __eq__(self, other):
        t1, t1u = self.t, self.u
        t2, t2u = other.t, other.u
        other.convert()
        self.convert()

        equal = abs(self.t - other.t) < .0001
        self.t, self.u = t1, t1u
        other.t, other.u = t2, t2u
        return equal

    def convert(self):
        if self.u.upper() == 'C':
            self.t *= 1.8
            self.t += 32
            self.u = 'F'

您也不想更改实际属性而不能在以后恢复值,存储,转换,进行比较然后将属性重置为原始值将意味着用户返回放入的内容。 / p>

答案 2 :(得分:0)

要比较温度,无需始终转换other。您只需在selfother具有不同单位时进行转化。一旦它们转换成相同的单位,就可以比较温度值。

您还从convert()方法返回了新对象。所以你需要分配返回值。并且您应该使用差异的绝对值来避免浮点错误。

这应该有效:

def __eq__(self, other):
    if self.u != other.u:
        other = other.convert()

    return math.fabs(self.t - other.t) < 1e-6

答案 3 :(得分:0)

  1. 转换为标准单位 - 假设您将华氏温度和摄氏温度转换为开尔文或始终转换为摄氏度

  2. 您转换的值是浮动的

  3. 您可以使用限制值

  4. 来允许舍入错误

    例如Python(2.75)

    keytool -importcert -file ~/example.crt -alias example -keystore $JAVA_HOME/jre/lib/security/cacerts -storepass changeit
    

答案 4 :(得分:0)

将内部温度存储在一个通用单元(如开尔文)中要简单得多。

def __init__(self, temp, unit):
    temp = float(temp)
    # Save the original input, perhaps for display purposes
    self.orig = temp
    self.unit = unit
    if unit == "K":
        self.t = temp
    elif unit == "C":
        self.t = tmp + 273.15
    elif unit == "F":
        self.t = (temp + 459.67) * 5 / 9.0
    else:
        raise ValueError("Unrecognized unit %s" % (unit,))

然后比较任意两个Temperature只是比较他们的t属性。

def __eq__(self, other):
    try:
        return abs(self.t - other.t) < 1e-6  # Or some other tolerance
    else AttributeError:
        return False
        # or raise NotImplemented