Im trying to debug my program, in which two classes, which are initialized by equal (note: ==
comparison not is
) arguments.
An example code + a snippet of the class + a object comparison is shown below.
Snippet Class Frame
def __init__(self, frame: PlaywrightFrame, page: Page) -> None:
super().__init__(frame)
self._impl_obj = frame._impl_obj
self._page = page
self._frame = frame
self._parent_frame = frame.parent_frame
self._origin_query_selector = frame.query_selector
frame.query_selector = self.query_selector
self._origin_query_selector_all = frame.query_selector_all
frame.query_selector_all = self.query_selector_all # type: ignore
self._origin_wait_for_selector = frame.wait_for_selector
frame.wait_for_selector = self.wait_for_selector
self._origin_add_script_tag = frame.add_script_tag
frame.add_script_tag = self.add_script_tag
self._origin_add_style_tag = frame.add_style_tag
frame.add_style_tag = self.add_style_tag
self._origin_frame_element = frame.frame_element
frame.frame_element = self.frame_element
self._origin_evaluate_handle = frame.evaluate_handle
frame.evaluate_handle = self.evaluate_handle
self._origin_wait_for_function = frame.wait_for_function
frame.wait_for_function = self.wait_for_function
self._origin_frame_locator = frame.frame_locator
frame.frame_locator = self.frame_locator
self._origin_locator = frame.locator
frame.locator = self.locator
frame0, page0 = frame._frame, frame._page
frame1, page1 = owner_frame._frame, owner_frame._page
print(frame0, frame1, frame0 == frame1)
print(page0, page1, page0 == page1)
new_frame0 = Frame(frame0, page0)
new_frame1 = Frame(frame1, page1)
print(new_frame0, new_frame1, new_frame0 == new_frame1)
print(new_frame0.__dict__.items() ^ new_frame1.__dict__.items())
print(DeepDiff(new_frame0, new_frame1))
Output
<Frame name= url='...'> <Frame name= url='...'> True
<Page url='...'> <Page url='...'> True
<Frame name= url='...'> <Frame name= url='...'> False
{('_origin_wait_for_function', <bound method Frame.wait_for_function of <Frame name= url='...'>>), ('_origin_locator', <bound method Frame.locator of <Frame name= url='...'>>), ('_origin_query_selector', <bound method Frame.query_selector of <Frame name= url='...'>>), ('_origin_wait_for_selector', <bound method Frame.wait_for_selector of <Frame name= url='...'>>), ('_origin_query_selector_all', <bound method Frame.query_selector_all of <Frame name= url='...'>>), ('_origin_query_selector_all', <bound method Frame.query_selector_all of <Frame name= url='...'>>), ('_origin_evaluate_handle', <bound method Frame.evaluate_handle of <Frame name= url='...'>>), ('_origin_add_script_tag', <bound method Frame.add_script_tag of <Frame name= url='...'>>), ('_origin_frame_locator', <bound method Frame.frame_locator of <Frame name= url='...'>>), ('_origin_add_style_tag', <bound method Frame.add_style_tag of <Frame name= url='...'>>), ('_origin_evaluate_handle', <bound method Frame.evaluate_handle of <Frame name= url='...'>>), ('_origin_locator', <bound method Frame.locator of <Frame name= url='...'>>), ('_origin_add_style_tag', <bound method Frame.add_style_tag of <Frame name= url='...'>>), ('_origin_query_selector', <bound method Frame.query_selector of <Frame name= url='...'>>), ('_origin_add_script_tag', <bound method Frame.add_script_tag of <Frame name= url='...'>>), ('_origin_frame_element', <bound method Frame.frame_element of <Frame name= url='...'>>), ('_origin_frame_locator', <bound method Frame.frame_locator of <Frame name= url='...'>>), ('_origin_wait_for_function', <bound method Frame.wait_for_function of <Frame name= url='...'>>), ('_origin_frame_element', <bound method Frame.frame_element of <Frame name= url='...'>>), ('_origin_wait_for_selector', <bound method Frame.wait_for_selector of <Frame name= url='...'>>)}
{'unprocessed': ["root: <Frame name= url='...'> and <Frame name= url='...'>"]}
I would recommend overriding the __eq__
method of the class, and put in the member variables that you want to compare.
Take the following snippet for example:
class SomeClass:
def __init__(self, a: int):
self.a = a
obj_1 = SomeClass(1)
obj_2 = SomeClass(1)
print(obj_1 == obj_2)
You will see that comparison fails (Output is False) because by default ==
for class objects compares id, which will definitely be different.
However, if you override the behaviour to compare the member variables that you want to compare, you can achieve what you desire:
from __future__ import annotations
class SomeClass:
def __init__(self, a: int):
self.a = a
def __eq__(self, other: SomeClass):
if not type(self) == type(other):
return False
return self.a == other.a
obj_1 = SomeClass(1)
obj_2 = SomeClass(1)
obj_3 = SomeClass(3)
print(obj_1 == obj_2)
print(obj_1 == obj_3)
The output of this is:
True
False
This is because now it is comparing the two classes as you asked it to compare, and not just the id
..
Cheers!