Pythonic way to wrap a subprocess call that takes a lot of parameters?
<p>I am writing a python script that provides a more user friendly API to a command line tool. Some of the necessary command calls take a lot of parameters (up to around 10 sometimes), but that is not good practice in Python. They can't just be defaults; it has to be possible to set all the parameters for a given call.</p>

<p>My current structure is an API class that has functions such as expose_image(), and then an interface class to handle the construction of the subprocess command and the call. I don't see that adding more classes will help, as the API class still has to generate and pass the parameters in some way.</p>

<p>One solution I have come up with is to fill a dictionary or namedtuple with the parameters and pass it as **kwargs, which makes things look a little nicer, but less explicit.</p>

<p>Is there a better way of handling this?</p>

<p>Thanks!</p>

<p>Like you said, <code>**</code> of kvargs are convenient way to <em>pass</em> several arguments to your function, however it always better to declare arguments explicitly in the function definition:</p>

<pre><code>def store(data, database,
          user, password,
          host=DEFAULT_HOST,
          port=PG_DEFAULT_PORT,
          chunk_size=64,
          flags=None):
     pass

# call
params = {"data": generate_data(),
          "database": "mydb",
          "user": "guest",
          "password": "guest",
          "chunk_size": 128
          }
store(**params)
</code></pre>

<p>Another way is to use "Parameters" class, like this (an example from <code>pika</code> library):</p>

<pre><code>class ConnectionParameters(Parameters):

    def __init__(self,
                 host=None,
                 port=None,
                 virtual_host=None,
                 credentials=None,
                 channel_max=None,
                 frame_max=None,
                 heartbeat_interval=None,
                 ssl=None,
                 ssl_options=None,
                 connection_attempts=None,
                 retry_delay=None,
                 socket_timeout=None,
                 locale=None,
                 backpressure_detection=None):

        super(ConnectionParameters, self).__init__()

        # Create the default credentials object
        if not credentials:
            credentials = self._credentials(self.DEFAULT_USERNAME,
                                            self.DEFAULT_PASSWORD)
        ...
# call
conn_params = pika.ConnectionParameters(host=self._host,
                                            port=self._port,
                                            credentials=cred)
conn = pika.BlockingConnection(parameters=conn_params)
</code></pre>

python subprocess parameter-passing args kwargs