Search code examples
pythonclassrefactoring

Is there any way to reduce number of arguments in a function without much refactoring the original function?


This question is related to Python: avoiding Pylint warnings about too many arguments

I have a function, which has many arguments. The highest vote answer in the above link suggests using a class as the argument. But, then, I need to work a bit on the original function to adapt the new argument as a class.

For example,

def operator(a, b, c, d, e, f, o):
    if o == 'a':
        return a + b + c + d + e + f
    if o == 'b':
        return a + b + d + d + e - f 

I can introduce a class

class input_entry:
    def __init__(self, a, b, c, d, e, f):
        self.a = a
        self.b = b    
        self.c = c    
        self.d = d    
        self.e = e    
        self.f = f    

input_item = input_entry(1,2,3,4,5,6)

then I need a revised function,

def operator_v2(input_item, o):
    a = input_item.a
    b = input_item.b
    c = input_item.c
    d = input_item.d
    e = input_item.e
    f = input_item.f

    if o == 'a':
        return a + b + c + d + e + f
    if o == 'b':
        return a + b + d + d + e - f    

Is there any shortcut from operator to operator_v2? In general, the arguments can be complicated, putting many entries into a list may be less suitable than introducing the class. (This example may not be ideal, since the class input_entry still have many arguments)


Solution

  • With @dataclass you have a lot less code duplication, and less boilerplate in order to reuse your original operator definition:

    from dataclasses import astuple, dataclass
    
    @dataclass
    class Operands:
        a: int
        b: int
        c: int
        d: int
        e: int
        f: int
    
    def operator(operands: Operands, o: str) -> int:
        a, b, c, d, e, f = astuple(operands)
        if o == 'a':
            return a + b + c + d + e + f
        if o == 'b':
            return a + b + d + d + e - f
    
    print(operator(Operands(1, 2, 3, 4, 5, 6), 'a'))  # 21