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?
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?
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}
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'
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}