I've seen How to use a context manager inside a decorator and how to pass an object created in decorator to decorated function as well as python decorators with parameters, and I'm trying to combine the two..but I'm struggling to get my head round it.
I'd much rather use the func tools @wrap
decorator to do this if possible, as I know if will preserve the doc string.
What I want to do is this:
def pyro_opener(func,service,database,port,secret_key):
def wrapper(params):
with Pyro4.Proxy("PYRO:"+service+"@"+database+":"+port) as obj:
obj.set_secret_key(secret_key)
return obj.func(params)
return wrapper
@pyro_opener(output_service, employee_db,port=9876,secret_key="h3llow0rld")
def get_employee_names(salary):
return obj.return_employee_names(salary) # obj is clearly not in scope here
# but what else can I do?
get_employee_names(25000)
>>>> Bob, Jane, Mary
I don't think this works this way, the method return_employee_names
is on the service at the other end of the connection. Should I just return the function call? If so how do I pass the params in then?
Wrappers around the functions are also knows as decorators which are a very powerful and useful tool in Python since it allows programmers to modify the behavior of function or class. Decorators allow us to wrap another function in order to extend the behavior of the wrapped function, without permanently modifying it.
contextmanager() uses ContextDecorator so the context managers it creates can be used as decorators as well as in with statements.
Decorators use a special syntax in JavaScript, whereby they are prefixed with an @ symbol and placed immediately before the code being decorated.
The purpose of having a wrapper function is that a function decorator receives a function object to decorate, and it must return the decorated function.
You'd pass in the object bound to with with ... as
to the wrapped function; the function would have to accept such an argument.
This is analogous to how methods work; they are just functions with an extra first argument (self
) passed in:
def pyro_opener(service, database, port, secret_key):
def decorator(func):
@wraps(func)
def wrapper(*args, **kw):
with Pyro4.Proxy("PYRO:{}@{}:{}".format(service, database, port)) as obj:
obj.set_secret_key(secret_key)
return func(obj, *args, **kw)
return wrapper
retutrn decorator
@pyro_opener(output_service, employee_db, port=9876, secret_key="h3llow0rld")
def get_employee_names(obj, salary):
return obj.return_employee_names(salary)
Note that I had to add another nested function in the pyro_opener()
to make it a proper decorator factory.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With