Kameron
Kameron

Reputation: 117

How to use Python Decorator to change only one part of function?

I am practically repeating the same code with only one minor change in each function, but an essential change.

I have about 4 functions that look similar to this:

def list_expenses(self):
    explist = [(key,item.amount) for key, item in self.expensedict.iteritems()] #create a list from the dictionary, making a tuple of dictkey and object values
    sortedlist = reversed(sorted(explist, key = lambda (k,a): (a))) #sort the list based on the value of the amount in the tuples of sorted list. Reverse to get high to low
    for ka in sortedlist:
          k, a = ka
          print k , a

def list_income(self):
    inclist = [(key,item.amount) for key, item in self.incomedict.iteritems()] #create a list from the dictionary, making a tuple of dictkey and object values
    sortedlist = reversed(sorted(inclist, key = lambda (k,a): (a))) #sort the list based on the value of the amount in the tuples of sorted list. Reverse to get high to low
    for ka in sortedlist:
        k, a = ka
        print k , a  

I believe this is what they refer to as violating "DRY", however I don't have any idea how I can change this to be more DRYlike, as I have two seperate dictionaries(expensedict and incomedict) that I need to work with.

I did some google searching and found something called decorators, and I have a very basic understanding of how they work, but no clue how I would apply it to this.

So my request/question:

  1. Is this a candidate for a decorator, and if a decorator is necessary, could I get hint as to what the decorator should do?

  2. Pseudocode is fine. I don't mind struggling. I just need something to start with.

Upvotes: 1

Views: 296

Answers (1)

Konstantin
Konstantin

Reputation: 3159

What do you think about using a separate function (as a private method) for list processing? For example, you may do the following:

def __list_processing(self, list): 
    #do the generic processing of your lists

def list_expenses(self):
    #invoke __list_processing with self.expensedict as a parameter

def list_income(self):
    #invoke __list_processing with self.incomedict as a parameter

It looks better since all the complicated processing is in a single place, list_expenses and list_income etc are the corresponding wrapper functions.

Upvotes: 4

Related Questions