On Wed, Aug 9, 2017 at 11:46 PM, Marko Rauhamaa <ma...@pacujo.net> wrote:
> Chris Angelico <ros...@gmail.com>:
>> On Wed, Aug 9, 2017 at 10:00 PM, Marko Rauhamaa <ma...@pacujo.net> wrote:
>>> Chris Angelico <ros...@gmail.com>:
>>>> Which means that its value won't change. That's what I said. Two
>>>> things will be equal regardless of that metadata.
>>> In relational-database terms, your "value" is the primary key and
>>> your "metadata" is the rest of the columns.
>> I would say the primary key is the "identity" and the rest of the
>> columns are the "value".
> Your response illustrates why you and I are not yet on the same page on
> this.
> Typically, an object's equality is simply the "is" relation. The only
> thing remaining for its usability as a key is a hash method. In fact,
> just defining:
>    def __hash__(self):
>        return 0
> will technically make any class applicable as a key or set member.

Yes, at the cost of making all your set operations into linear
searches. Basically, if all your objects have the same hashes, you
might as well use lists instead of sets, except that lists don't have
the methods/operators you want.

> The interesting fields of the object (which you disparagingly referred
> to as "metadata") don't need to participate in the calculation of the
> hash. You ought to pick the maximal collection of immutable fields as a
> basis of your hash, and you are all set (no pun intended).

The rules are (1) two objects that compare equal (__eq__) MUST have
the same hash; and (2) an object's hash must never change. Also, for
efficiency's sake, objects that compare unequal should ideally have
different hashes. That's why I refer to it as metadata; it's not
allowed to be part of the object's value, because two objects MUST
compare equal even if those other fields change. Can you give me a
real-world example of where two objects are equal but have important
attributes that differ?

>> But if you're defining "value" solely by the PK, then you have to ask
>> yourself what you're using this in a dictionary for - are you going to
>> construct multiple objects representing the same underlying database
>> row, and expect them to compare equal?
> Let's leave the relational world and return to objects.
> Really, the most obvious use case for hashed objects is their membership
> in a set. For example:
>     invitees = set(self.bff)
>     invitees |= self.classmates()
>     invitees |= self.relatives()

Okay. So you should define value by object identity - NOT any sort of
external primary key. That goes completely against your original
statement, which I shall quote again:

>>> In relational-database terms, your "value" is the primary key and
>>> your "metadata" is the rest of the columns.

If there is any possibility that you could have two objects in memory
with the same primary key but other attributes different, you'd have
major MAJOR problems with this kind of set operation. The best
solution would be to use the IDs themselves (as integers) in the set,
and ignore the whole question of identity and value.


Reply via email to