Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: Modify the internal behavior of a function by using decorator

I'm learning to use python decorator.

def my_dcrtr(fun):
    def new_fun():
        return fun()
    return new_fun

I realize the decorated function 'fun' acts like a black box inside the decorator. I can choose to use fun() or not at all inside new_fun. However, I don't know whether I can break into 'fun' and interact with fun's local scope inside the new_fun?

e.g. I'm trying to make a toy Remote Procedural Call (RPC) with python.

def return_locals_rpc_decorator(fun):
    def decorated_fun(*args, **kw):
        local_args = fun(*args, **kw)
        # pickle the local_args and send it to server
        # server unpickle and doing the RPC
        # fetch back server results and unpickle to results
        return rpc_results

    return decorated_fun


@return_locals_rpc_decorator
def rpc_fun(a, b, c=3):
    return locals() # This looks weird. how can I make this part of the decorator?


print(rpc_fun(2, 1, 6))

In this example, I try to get rpc_fun's argument list at runtime with the 'locals()' command. Then send it to server to execute. Instead of letting rpc_fun returns its locals(), is it possible to use the decorator to retrieve decorated function's argument space?

like image 671
Shichu Zhu Avatar asked Dec 04 '17 02:12

Shichu Zhu


People also ask

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.

What does the decorator do in Python?

Decorators provide a simple syntax for calling higher-order functions. By definition, a decorator is a function that takes another function and extends the behavior of the latter function without explicitly modifying it.

How do you call a function with a decorator in Python?

Python class decorator It is possible to use classes as decorators. For this, we need to implement the __call__ magic function. In the example, we use a class decorator to count the calls of a regular function. We call the update_wrapper function.

What is input decorator in Python?

A decorator is a function that takes another function as input, extends its behavior, and returns a new function as output.


1 Answers

You can use function annotations for Python3:

def return_locals_rpc_decorator(fun):
   def decorated_fun(*args, **kw):
      local_args = fun(*args, **kw) 
      print(local_args)
      fun_parameters = fun.__annotations__
      final_parameters = {a:list(args)[int(b[-1])-1] for a, b in fun_parameters.items() if a != 'return'}
      return final_parameters
   return decorated_fun

@return_locals_rpc_decorator
def my_funct(a:"val1", b:"val2", c:"val3") -> int:
    return a + b + c

print(my_funct(10, 20, 30))

Output:

60
{'a': 10, 'b': 20, 'c': 30}

In this way, you are using the wrapper function decorated_fun to access the decorated function's parameters and further information specified by the annotation. I changed the parameter descriptions in the annotations so that each string value would end in a digit that could be used to index args. However, if you do not want to change the parameter descriptions in the annotations, you can sort via ending character.

Edit: the code in the body of my_funct is executed when called in the wrapper function (decorated_fun), since the args, declared in the scope of decorated_fun is passed to and unpacked in local_args.

like image 85
Ajax1234 Avatar answered Nov 01 '22 13:11

Ajax1234