Python 在方法装饰器中处理cls和self

Python 在方法装饰器中处理cls和self,python,decorator,Python,Decorator,我有下面的问题,我试图找到最适合的方法。我有一个解决方案,但它只是感觉不到足够的蟒蛇。也许你知道一个更优雅的解决方案 问题是 在一个装修工,我想 查找函数参数的名称 从JSON字符串中提取参数 按正确的顺序将它们传递给函数 修饰符应该是所有函数类型的泛型,这些函数类型是静态方法,类方法,实例方法(带self)或函数方法(类外)。我编造了最后两个名字。如果您知道如何实际调用这些函数,请发表评论。非常感谢。这就产生了一个问题,即传递给装饰器的参数有时包含类对象或类实例,有时不包含 让我们假设我的项目

我有下面的问题,我试图找到最适合的方法。我有一个解决方案,但它只是感觉不到足够的蟒蛇。也许你知道一个更优雅的解决方案

问题是

在一个装修工,我想

  • 查找函数参数的名称
  • 从JSON字符串中提取参数
  • 按正确的顺序将它们传递给函数
  • 修饰符应该是所有函数类型的泛型,这些函数类型是
    静态方法
    类方法
    实例方法
    (带self)或
    函数方法
    (类外)。我编造了最后两个名字。如果您知道如何实际调用这些函数,请发表评论。非常感谢。这就产生了一个问题,即传递给装饰器的参数有时包含类对象或类实例,有时不包含

    让我们假设我的项目如下所示:

    import inspect
    
    @the_decorator
    def fun_method(name, password):
        pass
    
    class ExampleClass:
        @staticmethod
        @the_decorator
        def static_method(name, password):
            pass
    
        @classmethod
        @the_decorator
        def class_method(cls, name, password):
            pass
    
        @the_decorator
        def instance_method(self, name, password):
            pass
    
    我目前的解决方案

    def the_decorator(func):
        params = list(inspect.signature(func).parameters.keys())
    
        def get_func_args(data_json, keys):
            data_dict = json.loads(data_json)
            return [data_dict.get(p) for p in keys]
    
        @wraps(func)
        def wrapper(*args):
            if inspect.isclass(args[0]) or params[0] == 'self':
                func_args = get_func_args(args[1], params[1:])
                func_args = [args[0]] + func_args
            else:
                func_args = get_func_args(args[0], params)
    
            if None in func_args:
                raise ValueError('Not all necessary data was passed.')
    
            return func(*func_args)
    
        return wrapper
    

    1) 为什么需要查找参数的名称?我想你应该只关心他们的订单。2) 你真的想搞乱JSON,而不是简单地使用
    **kwargs
    (也称为关键字参数)?1)由于
    JSON.loads()
    返回一个
    dict
    ,它没有顺序,我无法确保参数将以正确的顺序传递给函数(name可以接收密码数据,反之亦然)2)是的,我想继续使用参数而不是
    kwargs
    。它更干净,而且我认为编写良好的decorator比在任何地方都使用kwargs要好。但是,您必须将JSON数据作为函数的参数之一传递,如
    函数('[123,“hello”,3.141,{“dictionary”:“yay!”}')
    。这就是你想要的吗?我明白你的意思,但是这些函数与API紧密相连,API总是接收和传递JSON字符串。我知道这会降低函数的可重用性,但是如果我想使用您描述的函数,那么我可以随时删除decorator,在必要时从JSON中提取args,并像往常一样调用函数,例如
    function(123,“hello”…)
    API使用JSON,因为它(JSON)它使您能够在支持该格式的代码之间传输数据,而不管它们是用什么语言编写的。JSON用于序列化。收到序列化对象后,通常会对其进行反序列化(即转换为语言的类型),然后仅继续使用反序列化版本。为什么每次调用函数时都要反序列化?它可能效率很低,导致代码难以理解。1)为什么需要查找参数的名称?我想你应该只关心他们的订单。2) 你真的想搞乱JSON,而不是简单地使用
    **kwargs
    (也称为关键字参数)?1)由于
    JSON.loads()
    返回一个
    dict
    ,它没有顺序,我无法确保参数将以正确的顺序传递给函数(name可以接收密码数据,反之亦然)2)是的,我想继续使用参数而不是
    kwargs
    。它更干净,而且我认为编写良好的decorator比在任何地方都使用kwargs要好。但是,您必须将JSON数据作为函数的参数之一传递,如
    函数('[123,“hello”,3.141,{“dictionary”:“yay!”}')
    。这就是你想要的吗?我明白你的意思,但是这些函数与API紧密相连,API总是接收和传递JSON字符串。我知道这会降低函数的可重用性,但是如果我想使用您描述的函数,那么我可以随时删除decorator,在必要时从JSON中提取args,并像往常一样调用函数,例如
    function(123,“hello”…)
    API使用JSON,因为它(JSON)它使您能够在支持该格式的代码之间传输数据,而不管它们是用什么语言编写的。JSON用于序列化。收到序列化对象后,通常会对其进行反序列化(即转换为语言的类型),然后仅继续使用反序列化版本。为什么每次调用函数时都要反序列化?它可能效率很低,导致代码难以理解。