Python装饰器将实例初始化变量转换为自我属性

时间:2019-02-03 11:38:33

标签: python

我看到某个地方的代码变成了:

@some_decorator
def __init__(args):

进入:

self.arg1 = arg1
self.arg2 = arg2

自动。我忘了怎么做。代码是什么?

3 个答案:

答案 0 :(得分:1)

你说的Data不是args,所以去了:

kwargs

打印:

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)

答案 1 :(得分:0)

满足您要求的装饰器将看起来如下:

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

并且可以像这样使用:

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'

答案 2 :(得分:0)

您可以将__dict__分配给带有在装饰器中生成的值的字典:

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)

输出:

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

但是,使用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)

输出:

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