title: Default Argument decorator python
body: <p>Python 3.6</p>
  
  <p>I'm attempting to create a decorator that automatically assigns the string of the argument as the default value. </p>
  
  <p>such as:</p>
  
  <pre><code>def example(one='one', two='two', three='three'):
      pass
  </code></pre>
  
  <p>would be equivalent to:</p>
  
  <pre><code>@DefaultArguments
  def example(one, two, three):
      pass
  </code></pre>
  
  <p>Here is my attempt (doesn't work.. yet..) <code>DefaultArguments</code>:</p>
  
  <pre><code>from inspect import Parameter, Signature, signature
  
  
  class DefaultArguments(object):
  
      @staticmethod
      def default_signature(signature):
          def default(param):
              if param.kind in (Parameter.POSITIONAL_OR_KEYWORD, Parameter.POSITIONAL_ONLY):
                  return param.replace(default=param.name)
              else:
                  return param
          return Signature([default(param) for param in signature.parameters.values()])
  
      def __init__(self, func):
          self.func = func
          self.sig = self.default_signature(signature(func))
  
      def __call__(self, *args, **kwargs):
          arguments = self.sig.bind(*args, **kwargs)
          return self.func(arguments)
  </code></pre>
  
  <p>The staticmethod <code>default_signature</code> creates the desired signature for the function, but I'm having difficulty assigning the new signature to the function. I'm trying to use Signature.<code>bind</code> I've read the <a href="https://docs.python.org/3/library/inspect.html" rel="noreferrer">docs</a> but i'm missing something.</p>
  
  <p><strong>EDIT</strong> </p>
  
  <p>Incorporating Ashwini Chaudhary's answer:</p>
  
  <pre><code>from inspect import Parameter, Signature, signature
  
  class DefaultArguments(object):
  
      @staticmethod
      def default_signature(signature):
          def default(param):
              if param.kind in (Parameter.POSITIONAL_OR_KEYWORD, Parameter.POSITIONAL_ONLY):
                  return param.replace(default=param.name)
              else:
                  return param
          return Signature([default(param) for param in signature.parameters.values()])
  
      def __init__(self, func):
          self.func = func
          self.sig = self.default_signature(signature(func))
          print(self.sig)
  
      def __call__(self, *args, **kwargs):
          ba = self.sig.bind(*args, **kwargs)
          ba.apply_defaults()
          return self.func(*ba.args, **ba.kwargs)
  </code></pre>