Coding rule for parsers and calculations
Here I (A. Togo) suggest some coding rules for parsers and calculations. The followings are not necessarily strict, but may be remembered.
Normally parsers and calculations should be able to be written straightforwardly from top to bottom in one simple flow. Each step in the flow can be well independent. If this is not the case, probably the data structure is not well designed.
Use of protected instance variables may not be very pythonic, but the code, especially parsers and calculations, can be huge to permit generality, and so for joint development, this makes us easy to trace the codes that are written by other people.
Instance variables in class starts with underscore, e.g., self._myvariable
. When we need to access this variable from outside of the class, we create the getter and setter by the decorators (@property
, @myvariable.setter
).
In __init__
method, we try to keep doing minimum definitions. If we want to do some involved work in __init__
, we can create another public method such as setup(self, ...)
and call it from outside.
Meta programing techniques are useful when we want to implement the code before knowing what we want to implement exactly. But when the code grows, it makes very hard for newly coming developers to read and understand the written code. In principle, parsers and calculators should be able to be written straightforwardly. So we can avoid the meta-programing techniques as much as possible.
We must avoid using the same variable name for different meanings. In its nature of parsers and calculators, we can have similar objects, but when the detailed meaning or the type is different, we must use the different variable names. This is useful to search or replace words by text editors and greps. Similarly, we should use the same variable names for the same meaning objects.
If possible, we should not modify the internal states of the passed container object to avoid side effects. But python is not the language for it. Passing a big container like a class instance to the other class is very convenient but dangerous. When the class is large and being inherited, it will be very tough to follow how and where the internal states of the container are modified.
The code fragments may be perhaps used in the future should not be kept in the shared branch. Other people can not understand it and then are mislead.
Often the comments are not updated even after the codes are updated. This brings us logical conflicts. If possible, the code itself explains well. But when we want to write comments in some reason, it is better to write in docstring of the method. Then, we are required to extract the part where comments are required (i.e., non-intuitive from the code itself) to another method to write the docstring. With an appropriate name of the method, even if the number of lines is small, it is worth to do it.