For Python 3.7+ you can use a Data Class, which is a very pythonic and maintainable way to do what you want.
It allows you to define fields for your class, which are your automatically initialized instance variables.
It would look something like that:
@dataclass
class Process:
PID: int
PPID: int
cmd: str
...
The __init__method will already be in your class.
Note that here type hinting is required, that is why I have used int and str in the example. If you don't know the type of your field, you can use Any from the typing module.
The Data Class has many advantages compared to the proposed solutions:
- It is explicit: all fields are visible, which respects the Zen of Python and makes it readable and maintainable. Compare it to the use of
**kwargs.
- It can have methods. Just like any other class.
- It allows you to go beyond the automatic
__init__ using the __post_init__ method.
EDIT: Reasons to avoid using NamedTuples
Some suggest the use of namedtuple for this case, but namedtuples have some behaviours that differs from Python classes, which are not really evident at first and should be well known:
1. NamedTuples are immutable
Immutability can be useful, but maybe it is not what you want for your instances. DataClasses can also be somehow immutable if you use the argument frozen=True on the @dataclass decorator.
2. NamedTuples __eq__ behaves like Tuple's
In Python, SomeNamedTuple(a=1, b=2) == AnotherNamedTuple(c=1, d=2) is True! The __eq__ function of NamedTuple, used in comparisons, only considers the values and the positions of those values on the compared instances, not their class or fields' names.