Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Code refactoring with python decorators?

I'm actually struggling with some piece of code. I do know that it can be refactored, but I can't find the nice-smart-elegant solution.

Here are two functions (much more functions of that kind are in my code):

def fooA(param1, param2):
    if param2 == True:
       code_chunk_1

    fooA_code  #uses only param1

    if param2 == True:
       code_chunk_2


def fooB(param1, param2):
    if param2 == True:
       code_chunk_1

    fooB_code  #uses only param1

    if param2 == True:
       code_chunk_2

My first idea was to use this decorator:

def refactorMe(func):
    def wrapper(*args):
        if args[-1]:
            code_chunk_1

        func(*args)

        if args[-1]:
            code_chunk_2

    return wrapper

And finally:

@refactorMe
def fooA(param1, param2):
    fooA_code  #uses only param1

@refactorMe
def fooB(param1, param2):
    fooB_code  #uses only param1

Unfortunately, I'm not happy with this solution:

  • This decorator is "intrusive" and specific to the fooA & fooB functions
  • param2 is not used anymore in the fooA & fooB body, but we must keep it in the function signature

Perhaps I'm not using the decorator for its initial purpose?

Is there any other way to refactor the code?

Thanks a lot!

like image 769
Thorfin Avatar asked Dec 06 '22 05:12

Thorfin


1 Answers

How about:

def call_one(func, param1, param2):
    if param2:
        code_chunk_1

    func(param1)

    if param2:
        code_chunk_2

def _fooA(param1):
    fooA_code  #uses only param1

def _fooB(param1):
    fooB_code  #uses only param1

def fooA(param1, param2):
    call_one(_fooA, param1, param2)

def fooB(param1, param2):
    call_one(_fooB, param1, param2)
like image 121
Ned Batchelder Avatar answered Dec 10 '22 10:12

Ned Batchelder