J'avais besoin de quelque chose dans le même but, mais aucune des réponses existantes ne couvrait tous les cas que j'ai testés. La réponse de Nadia était la plus proche de ce que je cherchais, alors j'ai commencé avec son code comme base.  
Le décorateur ci-dessous fonctionne avec toutes les combinaisons d'arguments valides:  
Positional                                          __init__(self, a, b                )
Keyword                                             __init__(self, a=None, b=None      )
Positional + Keyword                                __init__(self, a, b, c=None, d=None)
Variable Positional                                 __init__(self, *a                  )
Variable Positional + Keyword                       __init__(self, *a, b=None          )
Variable Positional + Variable Keyword              __init__(self, *a, **kwargs        )
Positional + Variable Positional + Keyword          __init__(self, a, *b, c=None       )
Positional + Variable Positional + Variable Keyword __init__(self, a, *b, **kwargs     )
Keyword Only                                        __init__(self, *, a=None           )
Positional + Keyword Only                           __init__(self, a, *, b=None        )
Il implémente également la _convention standard -prefix pour autoriser les __init__variables -private qui ne seront pas affectées aux instances de classe.  
from functools import wraps
import inspect
def auto_assign_arguments(function):
  @wraps(function)
  def wrapped(self, *args, **kwargs):
    _assign_args(self, list(args), kwargs, function)
    function(self, *args, **kwargs)
  return wrapped
def _assign_args(instance, args, kwargs, function):
  def set_attribute(instance, parameter, default_arg):
    if not(parameter.startswith("_")):
      setattr(instance, parameter, default_arg)
  def assign_keyword_defaults(parameters, defaults):
    for parameter, default_arg in zip(reversed(parameters), reversed(defaults)):
      set_attribute(instance, parameter, default_arg)
  def assign_positional_args(parameters, args):
    for parameter, arg in zip(parameters, args.copy()):
      set_attribute(instance, parameter, arg)
      args.remove(arg)
  def assign_keyword_args(kwargs):
    for parameter, arg in kwargs.items():
      set_attribute(instance, parameter, arg)
  def assign_keyword_only_defaults(defaults):
    return assign_keyword_args(defaults)
  def assign_variable_args(parameter, args):
    set_attribute(instance, parameter, args)
  POSITIONAL_PARAMS, VARIABLE_PARAM, _, KEYWORD_DEFAULTS, _, KEYWORD_ONLY_DEFAULTS, _ = inspect.getfullargspec(function)
  POSITIONAL_PARAMS = POSITIONAL_PARAMS[1:] 
  if(KEYWORD_DEFAULTS     ): assign_keyword_defaults     (parameters=POSITIONAL_PARAMS,  defaults=KEYWORD_DEFAULTS)
  if(KEYWORD_ONLY_DEFAULTS): assign_keyword_only_defaults(defaults=KEYWORD_ONLY_DEFAULTS                          )
  if(args                 ): assign_positional_args      (parameters=POSITIONAL_PARAMS,  args=args                )
  if(kwargs               ): assign_keyword_args         (kwargs=kwargs                                           )
  if(VARIABLE_PARAM       ): assign_variable_args        (parameter=VARIABLE_PARAM,      args=args                )
Remarque:
J'ai inclus des tests, mais je les ai regroupés dans la dernière ligne ( 58 ) par souci de concision. Vous pouvez étendre les tests, qui détaillent tous les cas d'utilisation potentiels, en find/replacemettant tous les $caractères avec une nouvelle ligne.
     
              
autoassignrecette d'activestate et uneautoargsimplémentation alternative sur: Quelle est la meilleure façon de faire l'attribution automatique d'attributs en Python, et est-ce une bonne idée? - Stack Overflow