добавить метод к классу динамически с декоратором - PullRequest
6 голосов
/ 25 февраля 2012

Я бы добавил метод к 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 заранее

Ответы [ 2 ]

12 голосов
/ 02 июля 2012

Это мой декоратор

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

Надеюсь, это полезно ичто тебе нужно:)

0 голосов
/ 11 июня 2019
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__
...