Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

add method to a class dynamically with decorator

I would have add method to a class dynamically... function name will also passed dynamically.

How can i do? I tried in this way

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

but if i do:

print(aClass.__dict__)

i have

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

instead of var:.....

i have this class:

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

i would call:

D.name()

and have back self.dimension but i don't know name in advance

like image 686
fege Avatar asked Feb 25 '12 11:02

fege


People also ask

Can we use decorator on class?

Decorators are a very powerful and useful tool in Python since it allows programmers to modify the behaviour of function or class.

Which decorator function is used to create a class method?

We use @classmethod decorator in python to create a class method and we use @staticmethod decorator to create a static method in python.

Can we use decorator inside a function in Python?

Nesting means placing or storing inside the other. Therefore, Nested Decorators means applying more than one decorator inside a function. Python allows us to implement more than one decorator to a function. It makes decorators useful for reusable building blocks as it accumulates the several effects together.


2 Answers

Here's a simplified py3 solution

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'
like image 96
citynorman Avatar answered Nov 03 '22 01:11

citynorman


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

Now you can use it like this:

class Foo:
    pass

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

Just remember to have self parameter in a function which you want to add to a class.

like image 21
mikus420 Avatar answered Nov 03 '22 01:11

mikus420