title: How to deal with multiple keyword arguments?
body: <p>I've got some trouble dealing with defining a user friendly function interface <strong>when passing two keyworded arguments with the same key</strong>. </p>
  
  <p><strong>Question</strong></p>
  
  <p>What is the best way to make it possible to call a function where <strong>two keyworded arguments have the same key</strong> and the <strong>second keyworded argument has precedence</strong>?<br>
  If this problem occurs, the first keyworded argument <strong>always stems from an unzipped database</strong> in a <code>dict</code>, while the second keyworded argument is always passed by giving it "directly" as a keyworded argument.<br>
  The database dictionary values <strong>must not be overwritten</strong> in the outer scopy of the functions, since they may be used multiple times.<br>
  edit: To keep up the usability of the function for the user, a <strong>backend-implementation</strong> is preferred. This means that the user can simply pass arguments to the function without the use of additional modules, while the function itself does all the magic.</p>
  
  <hr>
  
  <p><strong>Problem</strong></p>
  
  <p>I've got a function, called <code>fun_one</code> here, which receives a multitude of arguments defined directly by the user of my program. This may be <code>length</code> and <code>width</code> of a heat exchanger for example. To ease the use of the function and make the calling code as short as possible, the use of databases is encouraged. These databases contain the data in a <code>dict</code> (or in a pandas Series), in this case called <code>inputs</code>.<br>
  To pass the database-<code>dict</code> <code>inputs</code> to the function, it is unzipped with <code>**inputs</code> and thus passed as keyworded arguments.<br>
  <strong>Now if the user wants to overwrite a specific argument of the database</strong>, my understanding of a user-friendly approach would be to just let him pass the preceded argument again, for example with <code>length=23.7</code>, and internally overwrite the argument from the database. But of course (see example code) this raises the error before I can even enter the function where I could <code>try/except</code>:</p>
  
  <blockquote>
    <p>TypeError: fun_one() got multiple values for keyword argument 'length'</p>
  </blockquote>
  
  <p><strong>Code example reproducing the error</strong></p>
  
  <pre><code>def fun_one(*args, **kwargs):  # short example function
      print(kwargs)
  
  inputs = {'length': 15.8, 'width': 1.1, 'some_other_args': np.random.rand(3)}
  
  fun_one(**inputs, length=23.7)
  </code></pre>
  
  <hr>
  
  <p><strong>My current solution</strong></p>
  
  <p>My current solution <code>fun_two</code> involves <strong>not unzipping the database</strong> and passing it to <code>*args</code>. It checks <code>*args</code> for <code>dict</code>s and sets values <em>which are not yet in <code>kwargs</code> to <code>kwargs</code></em>, as shown in the code example below.  </p>
  
  <pre><code>def fun_two(*args, **kwargs):  # example function printing kwargs
      print(kwargs)  # print kwargs before applying changes
      for arg in args:  # find dicts
          if type(arg) is dict:
              for key, val in arg.items():  # loop over dict
                  _ = kwargs.setdefault(key, val)  # set val if key not in dict
      print(kwargs)  # print kwargs after applying changes
  
  inputs = {'length': 15.8, 'width': 1.1, 'some_other_args': np.random.rand(3)}
  
  fun_two(inputs, length=23.7)
  </code></pre>
  
  <p>But this approach is imho quite obscure for the user and requires looping and checking at the beginning of quite alot functions, since this will apply to numerous functions. (I'll outsource it to a module, so it is one line per function. But it still deviates from my understanding of an easy and clear function definition).</p>
  
  <p>Is there any better (more Pythonic) way to do this? Did I oversee some way to do it in the process of calling the function? Performance does not matter.<br>
  Thanks in advance!</p>