使用装饰器动态地向类添加方法

时间:2012-02-25 11:50:36

标签: python methods decorator

我会将方法添加到class动态...函数名称也将动态传递。

我该怎么办?我试过这种方式

def decor(*var):
  def onDecorator(aClass):
    class onInstance:
        def __init__(self,*args,**kargs):
            setter=var
            aClass.setter = self.flam
            self.wrapped = aClass(*args,**kargs)

        def __getattr__(self,attr):
            return getattr(self.wrapped,attr)

        def __setattr__(self,attr,value):
            if attr == 'wrapped':
                self.__dict__[attr]=value
            else:
                setattr(self.wrapped,attr,value)

        def flam(self,*args):
            self.__setattr__('dimension',len(args[0]))

    return onInstance
return onDecorator

但如果我这样做:

print(aClass.__dict__)

我有

'setter': <bound method onInstance.flam of <__main__.onInstance object at 0x522270>>

而不是var:.....

我有这堂课:

class D:
  def __init__(self, data):
    self.data = data
    self.dimension = len(self.data)

我会打电话:

D.name()

然后返回self.dimension,但我事先并不知道name

4 个答案:

答案 0 :(得分:10)

这是我的装饰者

def decorator(name):
    def wrapper(K):
        setattr(K, name, eval(name))
        return K
    return wrapper

这是一个示例方法

def myfunc(self):
    print "Istance class: ", self

这是一个解决的课程

@decorator("myfunc")
class Klass:
    pass

我希望这很有用,你需要什么:)

答案 1 :(得分:0)

def dec(cls):
    setattr(cls, 'c', 0)    # add atr counter to CLS

    def __init__(self):
        cls.c += 1  # +1 to CLS, not self!

    def get_c(self=None):
        return cls.c    # get current value from CLS


    setattr(cls, '__init__', __init__)  # add new __init__ IT WILL OVERWRITE original __init__
    setattr(cls, 'get_c', get_c)    # add new method
    return cls

@dec
class A:
    pass

print(A.c) # 0
user, _, _ = A(), A(), A()
user.get_c()  # 3

如果您想保存原始的 init 并将新值添加到def init

def __init__(self):
    cls.c += 1  # +1 to CLS, not self!
    cls.__init__

答案 2 :(得分:0)

这是简化的py3解决方案

class A(object):
    def a(self):
        print('a')

def add_b(cls):
    def b(self):
        print('b')

    setattr(cls, 'b', b)
    return cls

@add_b
class C(A):
    pass

C().b() # 'b'

答案 3 :(得分:0)

def add_method(cls):
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            return func(*args, **kwargs)

        setattr(cls, func.__name__, wrapper)
        return func
    return decorator

现在您可以像这样使用它:

class Foo:
    pass

@add_method(Foo)
def bar(self, parameter1):
    pass # Do something where self is a class instance

只要记住要添加到类中的函数中的self参数即可。