Python 如何编写一个decorator来在一个上下文管理器中封装一些需要参数的东西?

Python 如何编写一个decorator来在一个上下文管理器中封装一些需要参数的东西?,python,python-2.7,decorator,python-decorators,pyro,Python,Python 2.7,Decorator,Python Decorators,Pyro,我也看到了,我正试图将两者结合起来……但我正努力让自己的头脑清醒过来 如果可能的话,我更愿意使用func工具@wrapdecorator来实现这一点,因为我知道它是否会保留文档字符串 我想做的是: def pyro_opener(func,service,database,port,secret_key): def wrapper(params): with Pyro4.Proxy("PYRO:"+service+"@"+database+":"+port) as obj

我也看到了,我正试图将两者结合起来……但我正努力让自己的头脑清醒过来

如果可能的话,我更愿意使用func工具
@wrap
decorator来实现这一点,因为我知道它是否会保留文档字符串

我想做的是:

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\u employee\u names
在连接另一端的服务上。我应该只返回函数调用吗?如果是这样的话,我如何传入参数呢?

您将传入绑定到的对象,使用
和。。。与包装后的函数一样
;函数必须接受这样的参数

这类似于方法的工作原理;它们只是传递了额外第一个参数(
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\u opener()
中添加另一个嵌套函数,使其成为一个合适的装饰器工厂。

因此,当我调用
get\u employee\u names
时,从何处获取obj参数?另外,我认为使用
@wrapps
意味着我不需要额外的装饰性……?@Pureferret:仔细查看我的
get_employee_names()
版本;
obj
参数是显式的
functools.wrapps()
与装饰器工厂无关,一切都与将元数据从包装函数复制到包装器有关,这样包装器看起来更像原始的。@MartjinPiers我的意思是,当我想使用“get_employee_names”时,我需要提供obj参数(只需行我需要提供工资)。我不能像so
get_employee_name(???,300000)那样调用该方法
但是我应该为
添加什么呢?您不需要;装饰器包装器会传入该参数。就像在实例上调用方法一样,Python为您提供了
self
。请仔细查看
wrapper()
如何调用
func()