Search code examples
pythoninstance-variablesreadabilitycode-readability

Code Design when Dealing with Large Numbers of Instance Attributes in Python


So I'm writing a program in Python, and it's getting rather long. As I've expanded it, I've started to notice that some of my classes are getting many attributes, and I'm passing them into __init__ in a way that just feels suboptimal. As an example, here's what I'm talking about:

class Enemy(Ship):

def __init__(self,m=20000,size=32,F=[0,0],X=[0,0],v=[0,0],a=[0,0],p=[0,0],
             tau=0,theta=0,omega=0,alpha=0,I=850000,rel_X_cm=[16,16],sprites=[pygame.image.load("core_off.png"),pygame.image.load("core_on.png")],
             health=0,module_type="Thruster",module_coordinates=[0,0],core_module=None,
             module_orientation=0,F_max=[4000000,0],tau_max=0,
             attached_modules=[],surrounding_points = [[1,0],[0,1],[-1,0],[0,-1]]):

    super(Enemy,self).__init__(m,size,F,X,v,a,p,tau,theta,
                                  omega,alpha,I,rel_X_cm,sprites,
                                  health,module_type,module_coordinates,
                                  core_module,module_orientation,F_max,tau_max,
                                  attached_modules,surrounding_points)

This is obviously pretty messy, and I'd prefer to simplify my code. So my question is, is there a better way to handle all of these variables than the way I'm doing it?


Solution

  • That's exactly what unpacking arguments are for. And in this case since you are passing keyword arguments you can use **kwargs:

    def __init__(self,**kwargs):
        # do stuff with kwargs[X] which X is the name of your argument
    

    And for your positional arguments you can use one star prefix *args which lets you pass arbitrary argument list to function:

    def __init__(self,*args):
          # then you can loop over the args in order to achieve to arguments