0

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?

2
  • 1
    I would recommend following a structured OOP Python tutorial; you don't just throw self in everywhere and hope for the best! Think about which things are attributes of the object you're building, and which should be passed around as parameters of its methods. Commented Jun 12, 2016 at 15:37
  • @jonrsharpe I understand what you mean and I can see how my question is very naive, to say the least. But it was the only way I could some guideline and hints since I am a newbie in programming and Python. Commented Jun 12, 2016 at 16:25

1 Answer 1

1

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)
Sign up to request clarification or add additional context in comments.

3 Comments

Excellent explanation! Not only it works but also highlights the shortcomings in approach and programming skills. thanks
Small follow-up question; do you reckon that using the do_sums and pass in the self.dct and list objects (your 2nd suggestion) is better in terms of efficiency and code duplication compared to not using any such do_sums method and implementing as I describe in my first code block??
@nk-fford: there isn't really much difference here as the do_sums function is rather small.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.