我如何编写装饰器来将某些内容包装在带参数的上下文管理器中?
How do I write a decorator to wrap something in a context manager, that takes parameters?
我已经看过 as well as python decorators with parameters,我正在尝试将两者结合起来..但我正在努力解决这个问题。
如果可能的话,我更愿意使用 func 工具 @wrap
装饰器来执行此操作,因为我知道这是否会保留文档字符串。
我想做的是:
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
我认为这种方法行不通,方法 return_employee_names
在连接另一端的服务上。我应该 return 函数调用吗?如果是这样,我该如何传递参数?
您将绑定到 with ... as
的对象传递给包装函数;该函数将接受这样的参数。
这类似于方法的工作原理;它们只是传入一个额外的第一个参数 (self
) 的函数:
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)
请注意,我必须在 pyro_opener()
中添加另一个嵌套函数以使其成为合适的装饰器工厂。
我已经看过
如果可能的话,我更愿意使用 func 工具 @wrap
装饰器来执行此操作,因为我知道这是否会保留文档字符串。
我想做的是:
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
我认为这种方法行不通,方法 return_employee_names
在连接另一端的服务上。我应该 return 函数调用吗?如果是这样,我该如何传递参数?
您将绑定到 with ... as
的对象传递给包装函数;该函数将接受这样的参数。
这类似于方法的工作原理;它们只是传入一个额外的第一个参数 (self
) 的函数:
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)
请注意,我必须在 pyro_opener()
中添加另一个嵌套函数以使其成为合适的装饰器工厂。