-1

I saw somewhere code that turns:

@some_decorator
def __init__(args):

Into:

self.arg1 = arg1
self.arg2 = arg2

Automatically. I forgot how to do it. What is the code?

user3180
  • 1,369
  • 1
  • 21
  • 38

3 Answers3

1

well you said args not kwargs, so here goes:

def dec(f):
    def wrapper(*args):
        self = args[0]
        for i, v in enumerate(args[1:], 1):
            self.__dict__[f'arg{i}'] = v
        return f(*args)
    return wrapper

class MyC:
    @dec
    def __init__(self,*args):
        print(self.__dict__)

MyC(1,2,3)

prints:

{'arg1': 1, 'arg2': 2, 'arg3': 3}
sam46
  • 1,273
  • 9
  • 12
0

A decorator that accomplishes what you're asking would look life the following:

from functools import wraps
def init_kwargs(f):
     @wraps(f)                                                                       
     def wrapper(self, *args, **kwargs):
         self.__dict__.update(kwargs)
         return f(self, *args)
     return wrapper

And can be used like so:

class TestCase:
     @init_kwargs                                                                            
     def __init__(self):                                         
         pass

t = TestCase(argument_one="fun", argument_two="thing")
assert t.argument_one == 'fun'                                                                          
assert t.argument_two == 'thing'
Marcus
  • 3,216
  • 2
  • 22
  • 22
0

You can assign __dict__ to a dictionary with the generated values in the decorator:

def initialize(f):
  def _wrapper(_self, *args):
    _self.__dict__ = {f'arg{i}':a for i, a in enumerate(args, 1)}
    return f(_self, *args)
  return _wrapper

class Test:
   @initialize
   def __init__(self, *args):
      print(self.__dict__)

t = Test(1, 2, 3, 4)

Output:

{'arg1': 1, 'arg2': 2, 'arg3': 3, 'arg4': 4}

However, it is much cleaner to use setattr:

def initialize(f):
  def _wrapper(_self, *args): 
    for i, a in enumerate(args, 1):
      setattr(_self, f'arg{i}', a)
    return f(_self, *args)
  return _wrapper

class Test:
  @initialize
  def __init__(self, *args):
    print(self.__dict__)

t = Test(1, 2, 3, 4)

Output:

{'arg1': 1, 'arg2': 2, 'arg3': 3, 'arg4': 4}
Ajax1234
  • 69,937
  • 8
  • 61
  • 102