I sometimes use getattr(..)
to lazily initialise attributes of secondary importance just before they are used in the code.
Compare the following:
class Graph(object):
def __init__(self):
self.n_calls_to_plot = 0
#...
#A lot of code here
#...
def plot(self):
self.n_calls_to_plot += 1
To this:
class Graph(object):
def plot(self):
self.n_calls_to_plot = 1 + getattr(self, "n_calls_to_plot", 0)
The advantage of the second way is that n_calls_to_plot
only appears around the place in the code where it is used. This is good for readability, because (1) you can immediately see what value it starts with when reading how it's used, (2) it doesn't introduce a distraction into the __init__(..)
method, which ideally should be about the conceptual state of the class, rather than some utility counter that is only used by one of the function's methods for technical reasons, such as optimisation, and has nothing to do with the meaning of the object.