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

feg*_*ege 6 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
Run Code Online (Sandbox Code Playgroud)

但如果我这样做:

print(aClass.__dict__)
Run Code Online (Sandbox Code Playgroud)

我有

'setter': <bound method onInstance.flam of <__main__.onInstance object at 0x522270>>
Run Code Online (Sandbox Code Playgroud)

而不是var:.....

我有这堂课:

class D:
  def __init__(self, data):
    self.data = data
    self.dimension = len(self.data)
Run Code Online (Sandbox Code Playgroud)

我打电话给:

D.name()
Run Code Online (Sandbox Code Playgroud)

并且已经回来self.dimension但我name事先并不知道

小智 13

这是我的装饰师

def decorator(name):
    def wrapper(K):
        setattr(K, name, eval(name))
        return K
    return wrapper
Run Code Online (Sandbox Code Playgroud)

这是一种示例方法

def myfunc(self):
    print "Istance class: ", self
Run Code Online (Sandbox Code Playgroud)

这是一个decoreted类

@decorator("myfunc")
class Klass:
    pass
Run Code Online (Sandbox Code Playgroud)

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


cit*_*man 6

这是一个简化的 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'
Run Code Online (Sandbox Code Playgroud)

  • 这是这里所有解决方案中最优雅的 (2认同)