This is an old revision of the document!
Python extras
These extra sections are slightly more advanced python topics which will be useful for the project.
Dataclasses
Dataclasses are a shorthand way of implementing certain methods and generally removing some boilerplate code.
Assume you're writing a class to implement linked lists, which can be printed in a similar way to ADT's (so [1,2,3] should be printed as Cons(1,Cons(2,Cons(3,Empty())))). Your code may look like this:
class List: pass class Empty(List): def __str__(self): return 'Empty()' def __repr__(self): return str(self) class Cons(List): def __init__(self, head, tail): self.head = head self.tail = tail def __str__(self): return f'Cons({self.head},{self.tail})' def __repr__(self): return str(self)
contrast this to how a similar level of functionality would be implemented in haskell:
data List a = Cons a List | Empty deriving Show
Is it possible to eliminate most of the boilerplate code present in the python version while keeping most of the functionality? YES, using dataclasses.
dataclass
is a type of python object known as a decorator. In general, decorators are placed right before a class or function definition (preappended with the @
symbol) and alter their behaviour in certain ways. In our case, the dataclass
decorator implements some generic methods of the class, most importantly, __init__
, __str__
and __repr__
. If we want our class to contain member variables, we only need to list them in the fucntion body. The list code rewritten with dataclasses looks like this:
from dataclasses import dataclass class List: pass @dataclass class Empty(List): pass # will automatically implement a str and repr method @dataclass class Cons(List): head: any tail: List
Now, the downside is that we lose some control over the specific implementations of the autogenerated methods. For example, the default behaviour for the __str__
and __repr__
methods also adds the name of the attribute in the representation (for example, we get Cons(head=1, tail=Empty())
instead of Cons(1,Empty)
).
There are options to disable certain methods from being generated or add extra ones, by giving arguments to the dataclass
decorator. For this, and further reading on this topic, please refer to the official documentation for dataclasses.