【问题标题】:Decorator: Maintain state装饰器:保持状态
【发布时间】:2017-05-08 10:33:02
【问题描述】:

我需要编写有关给定信息的信息,例如给定函数采用什么参数等。我想做的例子是

@author("Joey")
@parameter("name", type=str)
@parameter("id", type=int)
@returns("Employee", desc="Returns employee with given details", type="Employee")
def get_employee(name, id):
     //
     // Some logic to return employee
     // 

装饰器的骨架如下:

json = {}
def author(author):
    def wrapper(func):
         def internal(*args, **kwargs):
              json["author"] = name
              func(args, kwargs)
         return internal 
    return wrapepr

同理,参数装饰器也可以写成:

def parameter(name, type=None):
    def wrapper(func):
         def internal(*args, **kwargs):
              para = {}
              para["name"] = name
              para["type"] = type
              json["parameters"].append = para
              func(args, kwargs)
         return internal 
    return wrapepr

同样,也可以编写其他处理程序。最后,我可以只调用一个函数,该函数将为每个函数获取所有已形成的 JSON。

最终输出可能是

[
{fun_name, "get_employee", author: "Joey", parameters : [{para_name : Name, type: str}, ... ], returns: {type: Employee, desc: "..."}
{fun_name, "search_employee", author: "Bob", parameters : [{para_name : age, type: int}, ... ], returns: {type: Employee, desc: "..."}
... 
}
]

我不确定如何维护状态并知道如何整合有关一个功能的数据应该一起处理。

我怎样才能做到这一点?

【问题讨论】:

    标签: python decorator python-decorators


    【解决方案1】:

    我不知道我是否完全了解您的用例,但是将作者添加到您当前的功能中是否行不通:

    func_list = []
    
    def func(var):
         return var
    
    json = {}
    json['author'] = 'JohanL'
    json['func'] = func.func_name
    func.json = json
    
    func_list.append(func.json)
    
    def func2(var):
         return var
    
    json = {}
    json['author'] = 'Ganesh'
    func2.json = json
    
    func_list.append(func2.json)
    

    这可以使用如下装饰器自动完成:

    def author(author):
        json = {}
        def author_decorator(func):
            json['func'] = func.func_name
            json['author'] = author
            func.json = json
            return func
        return author_decorator
    
    def append(func_list):
        def append_decorator(func):
            func_list.append(func.json)
            return func
        return append_decorator
    
    func_list = []
    
    @append(func_list)
    @author('JohanL')
    def func(var):
         return var
    
    @append(func_list)
    @author('Ganesh')
    def func2(var):
         return var
    

    然后您可以访问json dict 为func.jsonfunc2.json 或在func_list 中查找函数。请注意,要让装饰器工作,您必须按照我放置它们的顺序添加它们,并且我没有添加任何错误处理。

    此外,如果您希望不显式传递 func_list,而是使用具有显式名称的全局定义列表,则代码可以简化为:

    func_list = []
    
    def author(author):
        json = {}
        def author_decorator(func):
            json['func'] = func.func_name
            json['author'] = author
            func.json = json
            return func
        return author_decorator
    
    def append(func):
        global func_list
        func_list.append(func.json)
        return func
    
    @append
    @author('JohanL')
    def func(var):
         return var
    
    @append
    @author('Ganesh')
    def func2(var):
         return var
    

    也许这对你来说已经足够了?

    【讨论】:

    • 当有另一个作者Ganeshfunc2 时会出现问题。我们需要创建输出[{func: 'func', author: "JohanL"}, {func: "func2", author: "Ganesh."}] 该方法是否适用于第二个功能?
    • 这将适用于您的两个功能,如我在更新示例中所示。每个都有一个唯一的 json dict。
    • 感谢@JohanL 的解释。是的。这两个 JSON 是根据 JSON 生成的。但最终输出是所有此类 JSON 的列表。为此,我们需要创建另一个装饰器,对吧?并且只需要在第一个装饰器之后调用该装饰器吗?
    • 我已经用第二个装饰器更新了我的答案,它将函数附加到 func_list。
    • 感谢您的回答。这很好,但可以在不显式传递参数func_list 的情况下实现自动化。我正在尝试将其作为一个库,用户不需要显式传递参数。
    猜你喜欢
    • 1970-01-01
    • 2019-07-22
    • 2020-12-20
    • 2015-10-01
    • 2017-11-18
    • 2011-12-24
    • 1970-01-01
    • 2017-06-19
    • 1970-01-01
    相关资源
    最近更新 更多