Search code examples
pythonclasspython-3.xself

Creating a function inside a class with self variables as arguments (Python)


Inside a class I want to create a method that would have as arguments some self. variables.

For example (some code taken from here), say that I have

class Summations(object):
    dct = {'A': 11, 'B': 4, 'C': 7, 'D': 12, 'E': 5, 'L': 2, 'M': 0, 'Z': 9}

    f_lst = ['A', 'B', 'C', 'D', 'E', 'F', 'G']
    s_lst = ['H', 'I', 'J']
    t_lst = ['K', 'L', 'M', 'N']

    def get_results(self):
        # Sum each of the dictionary's values provided their corresponding keys exist in a specified list.

        f_sum = sum(self.dct.get(k, 0) for k in self.f_lst)
        s_sum= sum(self.dct.get(k, 0) for k in self.s_lst)
        t_sum= sum(self.dct.get(k, 0) for k in self.t_lst)

I am trying to avoid the repeated code from all the summations inside the get_results and create a separate class method to handle these summations, something like this:

def do_sums(self, d, l):
    return sum(self.d(k, 0) for k in self.l)

and have the do_sums be called inside the get_results like so

f_sum = self.do_sums(self, dct, f_lst)
s_sum = self.do_sums(self, dct, s_lst)
t_sum = self.do_sums(self, dct, t_lst)

Is something like this (self variables of a class used as arguments in that classe's method) even possible? And if yes, how will the syntax look like?


Solution

  • You can use getattr() to access attributes dynamically; give the object to look the attribute on (self here) and a string with the name of the attribute:

    def do_sums(self, d, l):
        return sum(getattr(self, d).get(k, 0) for k in getattr(self, l))
    

    and pass in names:

    f_sum = self.do_sums('dct', 'f_lst')
    s_sum = self.do_sums('dct', 's_lst')
    t_sum = self.do_sums('dct', 't_lst')
    

    There is no need to pass in self since self.do_sums() is a bound method.

    But you already know your attributes when you call the method, so you could just pass in the objects directly:

    def do_sums(self, d, l):
        return sum(d.get(k, 0) for k in l)
    

    and pass in the self.dct and list objects:

    f_sum = self.do_sums(self.dct, self.f_lst)
    s_sum = self.do_sums(self.dct, self.s_lst)
    t_sum = self.do_sums(self.dct, self.t_lst)