Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

decorating a method in python

Tags:

python

I am making a little wrapper module for a public library, the library has a lot of repetition, where after object creation, maybe methods require the same data elements.

I have to pass the same data in my wrapper class, but don't really want to pass the same thing over and over. So I would like to store the data in my wrapper Class and apply it if it is not included in the method. However if things get hairy down the road, I want the method arguments to overwrite class defaults. Here is a code snippet that illustrates my goals.

class Stackoverflow():
    def __init__(self,**kwargs):
        self.gen_args = {}
        #Optionally add the repeated element to the object 
        if 'index' in kwargs:
            self.gen_args['index'] = kwargs['index']
        if 'doc_type' in kwargs:
            self.gen_args['doc_type'] = kwargs['doc_type']

    #This is where the problem is        
    def gen_args(fn):
        def inner(self,*args,**kwargs):
            kwargs.update(self.gen_args)
            return fn(*args,**kwargs)
        return inner

    #There is a bunch of these do_stuffs that require index and doc_type
    @gen_args
    def do_stuff(self,**kwargs):
        print(kwargs['index'])
        print(kwargs['doc_type'])

#Just send arguments up with the method
print("CASE A")        
a = Stackoverflow()
a.do_stuff(index=1,doc_type=2)

#Add them to the class and have all methods use them without having to specify 
#them each time
print("CASE B")  
b = Stackoverflow(index=1,doc_type=2)
b.do_stuff()

#The arguments specified in the method should overwrite class values
print("CASE C")  
c = Stackoverflow(index=1,doc_type=2)
c.do_stuff(index=3,doc_type=4)

EDIT:

So the question is, how do I fix the gen_args or is there a better way to do this? The specific error I get with this code is: return fn(*args,**kwargs) TypeError: do_stuff() missing 1 required positional argument: 'self'

like image 947
nick_v1 Avatar asked Apr 23 '15 00:04

nick_v1


1 Answers

I might use this definition of inner:

    def inner(self,*args,**kwargs):
        return fn(self, *args,**dict(self.gen_args, **kwargs))

Notes:

  • This version provides self, which is missing in your version.
  • This gives priority to the passed-in kwargs.
like image 91
Robᵩ Avatar answered Sep 27 '22 23:09

Robᵩ