Reputation: 171
I have the following question: My python scripts parses .pdf documents and return found order information as an instance of this class:
@dataclass
class BasicOrder:
order_id: str = ''
supplier_name: str = ''
supplier_order_id: str = ''
client_order_id: str = ''
base_name: str = ''
container_no: str = ''
seal_no: str = ''
However, more often than not document don't have complete order information, so I have to query the database to find if there is more information.
So I end up with two objects: of BasicOrder class: order_from_pdf and order_from_db, one have some attributes filled (for example container_no
and seal_no
), other have order_id, supplier_name
, etc. (what is known from pdf and db can be very random, since different documents have different data and not always filled correctly)
Finally, I have to 'smash' them together into one complete object, I use this function:
def update_dict(self, another_object_dict: dict):
for key, value in self.__dict__.items():
if not value and another_object_dict[key]:
self.__dict__[key] = another_object_dict[key]
Here is the question: can I somehow pass another object instance instead of dict?
It gives me Unresolved reference 'BasicOrder'
if to use it as an argument.
Or maybe there is more 'clean' way to do this?
Solution found: after some consideration, I've decided that to have class method that updates itself by another instance is kinda dumb, insdead I just create new fused order after I've got pdf and db version inside the method that does comparison. That, IMO is the cleanest solution here.
Upvotes: 0
Views: 803
Reputation: 485
You can use the asdict
function from dataclasses rather than __dict__
to make sure you have no side effects. Here is small example:
import dataclasses
from typing import Optional
@dataclasses.dataclass
class Foo:
attr_1: str
attr_2: Optional[int] = None
attr_3: Optional[str] = None
def combine_with_other(self, other: "Foo") -> "Foo":
attribute_dict_other = dataclasses.asdict(other)
attribute_dict_self = dataclasses.asdict(self)
merged_dict = {
key: attribute_dict_other[key] if attribute is None else attribute
for key, attribute in attribute_dict_self.items()
}
return Foo(**merged_dict)
here is the output:
>>> db_version = Foo("foo", attr_3="attr_3")
>>> local_version = Foo("foo", 42)
>>> print(local_version.combine_with_other(db_version))
Foo(attr_1='foo', attr_2=42, attr_3='attr_3')
Upvotes: 1