add method to a class dynamically with decorator

10,743

Solution 1

This is my decorator

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

This is a sample method

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

This is a decoreted class

@decorator("myfunc")
class Klass:
    pass

I hope this is useful and what you need :)

Solution 2

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'

Solution 3

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.

Share:
10,743

Related videos on Youtube

fege
Author by

fege

Updated on June 04, 2022

Comments

  • fege
    fege about 2 years

    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

    • Karl Knechtel
      Karl Knechtel over 12 years
      Show an example of the code that you hope to use to attach the method to the class. I have no idea how you could have a method that you want to attach, but not have any kind of name for it. I also have no idea how you expect the method to make any sense to be attached to the class, if the class wasn't designed with that method in the first place.
    • 550
      550 over 3 years
      Years later, but showing a good and simple solution: medium.com/@mgarod/…
  • S P Sharan
    S P Sharan almost 3 years
    This is the most elegant of all solutions here