The common way to define a class
When trying to encapsulate a class in python, we use __init__
to carry out parametric construction. Just like below:
class Message:
def __init__(self, mid:int, text:str) -> None:
self.__id: int = mid
self.__text: str = text
Sometimes, we don't want to expose the complex processing logic of variables, but only output the final atrributr value that cannot modified. Property modifier is suggested.
@property
def id(self) -> int:
return self.__id
@property
def text(self) -> str:
return self.__text
However if we create an instance object, and try to print it, the address of the object registered in memory will be output. So how to make it easier to identify? We can use __repr__
to log it.
def __repr__(self) -> str:
return "{}(id = {}, text = {})".format(self.__class__.__name__,self.id,self.text)
Sounds great. Now that we have reached here, some other methods can be added by the way. Like "compare" or "hash".
def __eq__(self,other:object) -> ...:
if other.__class__ is self.__class__:
return (self.id, self.text) == (other.id.other.text)
else:
return NotImplemented
def __hash__(self) -> int:
return hash(self.__class__, self.id, self.text)
Anyway, we have realized the function we want. Your hands leave the keyboard, but suddenly there is a new demand. You have to modefy each method, which sounds not very good.
dataclass
But in dataclass, you can realize it just in a few lines. If a new demanded is created, you can just add in a variable.
@dataclass(frozen=True, order=True)
class Message:
id: int
text: str
#frozen=True means the function is immutable and hashable
Also, we can use aatuple or as dict to format the output
def main():
msg = Message(12, 'great')
print(msg)
print(dataclasses.astuple(msg))
print(dataclasses.asdict(msg))
Especially, when your project is complex, it is a fantastic way.