-2
from dataclasses import dataclass

@dataclass
class ThreeDPoint:
    x: int | float
    y = 0.0
    z: int | float = 0.0

point_1 = ThreeDPoint(1.0,2)

point_3 = ThreeDPoint(1,2)
print(point_1 == point_3)

The result is true.

I ran it in python playground. The result said it is true. I think this dataclass module might play some magic trick inside but I am not sure what is exactly happening.

5
  • 6
    What makes you think they shouldn't be equal? What does 1.0 == 1 give you? Commented Oct 1, 2023 at 17:52
  • The designers of Python decided that integer 1 is equal to float 1.0. Commented Oct 1, 2023 at 17:55
  • 4
    Also, why is this question tagged with python 2.7? Dataclasses certainly did not exist back then... Commented Oct 1, 2023 at 17:57
  • 2
    The other issue is that dataclass overrides the == operation, and compares instances by comparing the attributes (similar to the way dictionaries are compared). Commented Oct 1, 2023 at 17:59
  • @JohnGordon: Not to mention the designers of basically every language above the assembly level. (Save extremely type-strict languages like Rust, which simply forbid the comparison) Commented Oct 1, 2023 at 18:10

2 Answers 2

0

There is no magic trick. In Python, integer 1 and float 1.0 are the same

> 1 == 1.0
True

On the other hand, type(1) is not the same as type(1.0)

> type(1) == type(1.0)
False

If you would like the equality operator to behave the way you suggested (= returning False when x has the same value but different type), then you could define your own equality method for the class, like so:

from dataclasses import dataclass


@dataclass
class ThreeDPoint:
    x: int | float
    y = 0.0
    z: int | float = 0.0

    def __eq__(self, other):
        for var, var_value in self.__dict__.items():
            try:
                other_var_value = getattr(other, var)
                if not (var_value == other_var_value and type(var_value) is type(other_var_value)):
                    return False
            except AttributeError:
                return False
        return True


point_1 = ThreeDPoint(1.0, 2)
point_3 = ThreeDPoint(1, 2)
print(point_1 == point_3)
Sign up to request clarification or add additional context in comments.

5 Comments

Hmm, you don't need to iterate over the other dictionary to define "found", you just try to grab the attribute and handle a KeyError. other_var_value = getattr(other, var).
Simpler and faster without the loop (and properly using is/is not for the type comparison): Attempt This Online!
You are right guys @ShadowRanger, Guimoute, I wrote it very fast without testing or checking it much. Edited the answer. Thx
@JosefJoeSamanek: If you want AttributeError to be raised for you to handle, get rid of the third argument to getattr (which is returned instead of raising an AttributeError, and could be mistaken for the correct value if any of the attributes could legally take a value of False).
Thx, fixed (leftover from previous version)
0

1.0 equals to 1 in python, so 1.0 == 1 will return true. Just like Barmar said, when you compare dataclasses you are comparing instances using their attributes, so

1.0 == 1 is true.

2 == 2 is true

Therefore, ThreeDPoint(1.0,2) == ThreeDPoint(1,2) is true.

1 Comment

thank you, I am a beginner of learning python. I thought one is int another is float and point_1 or 3 return a class containing different type of numbers so I consider this might not equal and I was confused of it. now all cleared, thanks

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.