Django:何时需要使用__eq__方法?

4
在Django中,我编写了一个自定义的基于类的验证器,并实现了__eq__方法,因为这也是Django本身已经实现的验证器所做的。
以下是代码示例:
@deconstructible
class FileSizeValidator:

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

    def __call__(self, value):
        limit = self.mb * 1024 * 1024
        if value.size > limit:
            raise ValidationError('File too big (max. ' + str(self.mb) + ' MiB).')

    def __eq__(self, other):
        return (
            isinstance(other, FileSizeValidator) and
            self.mb == other.mb
        )

现在,我已经为 ImageField 编写了一个自定义类。我想将其用于 ImageField 模型中的 upload_to= 参数。以下是我的示例:

@deconstructible
class RandomFileName:

    def __init__(self, directory=''):
        self.directory = directory

    def __call__(self, instance, filename):
        return self.directory + ("/" if self.directory else '') + get_random_string(7) + "." + filename.split('.')[-1]

    def __eq__(self, other):
        return (
            isinstance(other, RandomFileName) and
            self.directory == other.directory
        )

总体来说,我对它感到满意,似乎也运行良好。我只是不知道何时需要使用__eq__方法,希望您能给出解释。

1个回答

2
这被称为运算符重载,在你的例子中,它用于比较两个对象。实现__eq__()方法后,您可以将任何其他对象与您的对象进行相等比较。
我们现在可以从您的类中创建两个对象:
obj1 = FileSizeValidator(100)
obj2 = FileSizeValidator(200)

我们可以使用obj1 == obj2来比较它们。

由于我们定义了自定义的__eq__(),这将比较对象的classmb属性的值,以返回TrueFalse值。如果任何条件失败,它将返回False

在Python中,默认情况下,用于两个自定义对象的等号运算符会比较对象的id值,并且除了将对象与其自身进行比较之外,永远不会返回True


是的,我知道。我只是想知道什么时候和为什么需要这些方法? - Aliquis
@Aliquis 当你想要使用自定义条件比较两个对象时,就像在这个例子中你正在匹配 mb 属性的值。可能会有10个以上的属性具有不匹配的值,但如果此值匹配,则其他任何事情都无关紧要。 - Ankit Jaiswal
让我换一种方式问:为什么Django为其验证器实现__eq__? - Aliquis
在Python中,默认情况下,没有两个自定义类对象会相等。一个对象只会等于它本身。因此,要比较两个对象是否相等,您需要重载等号运算符。 - Ankit Jaiswal
那么我在想是否应该重写 RandomFileName 类的 __eq__ 方法呢? - Aliquis
不,如果您不希望比较该类的两个对象。 - Ankit Jaiswal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接