I have recently started using classes in Python since I realized how useful they could be, but I'm still beginning to grasp the best practices when designing them.
So when I define my classes, usually I end up defining a lot of attributes in the __init__ method (or other method that initializes them), storing them in self and after that having to load all of them for each other method in which I may want to use them, as in the example that follows:
class MyClass:
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
def foo(self):
a = self.a
b = self.b
c = self.c
''' Perform some operations with a, b and c '''
This may look OK with two or three attributes, but when the number of attributes that I need increases (up to 10-20), I feel this practice becomes less clean and a lot of code repeats itself with lines like a = self.a, b = self.b, ... all the time.
Also, the alternative of avoiding the lines like a = self.a and just calling self.a when I need it is not that appealing when there are many attributes, since the code starts getting cluttered with self's everywhere and becomes hard to read. Are there better approaches for this? Would you recommend me to look into some Python topic that I may be missing?
Thank you!
EDIT: to give a practical example where this issue arises: I want to create a class that implement some methods to initialize a neural network, give some default attributes that I usually use, train the network, postprocess it to get specific metrics from the model on different test sets... That is why I might find it useful to access some attributes like number of nodes per layer, number of hidden layers, solver type, regularization, etc.
For instance:
class nn_api:
def init_default(self, w_size, n_hidden):
self.w_size = w_size
self.shift = 1
self.stride = 1
self.n_neurons = 128
self.n_hidden = n_hidden
self.activation = 'elu'
self.batch_size = 32
...
def collect_data(self):
...
def build_model(self):
...
def fit(self):
...
def postprocess(self):
...
self.aeverywhere is that this makes it obvious that the reference is an instance attribute. A bareacould be anything.