celery传参时的对象转换

遇到一个有趣的问题,celery delay传入SSH的对象时,报错Object of type SSH is not JSON serializable,分析一下就是只能传json的数据。把所有传入的数据都转成json。

1、因为我传递的是对象,所以要把对象转成json,所以我就自定义了一个JSONEncoder

class MyEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, SSH):
            obj.__dict__['arguments']['pkey'] = None
            return obj.__dict__

2、在异步任务里面又将json转成对象

@app.task(name='receive_execute_command', base=CustomTask)
def execute_remote_command(client: json, scripts: str):
    """
    异步执行远程脚本
    :param client:
    :param scripts:
    :return:
    """
    client_json_to_dict = json.loads(client)
    client_json_to_dict['arguments']['pkey'] = SSH.get_private_key()

    new_client_obj = SSH(hostname='none', password='none')
    new_client_obj.__dict__ = client_json_to_dict

    res = new_client_obj.exec_command(scripts, timeout=5)
    return res[1].decode('utf-8')

3、这是调用异步的片段

        elif is_async:
            client_to_json = json.dumps(client, cls=MyEncoder, indent=4)
            execute_remote_command.delay(client_to_json, scripts)
            return ['0', '异步执行中。'.encode('utf-8')]

4、总结下来难点就是对象与json之间的互转。希望能帮助到各位大侠。

5、扩展一下__dict__ (magic方法)

为了方便用户查看类中包含哪些属性,Python 类提供了 __dict__ 属性。需要注意的一点是,该属性可以用类名或者类的实例对象来调用:

  1)用类名直接调用 __dict__,会输出该由类中所有类属性组成的字典;

  2)而使用类的实例对象调用 __dict__,会输出由类中所有实例属性组成的字典。

对于具有继承关系的父类和子类来说,父类有自己的 __dict__,同样子类也有自己的 __dict__,它不会包含父类的 __dict__。

可以参考:http://c.biancheng.net/view/2374.html

posted @ 2023-04-24 14:48  JvvYou  阅读(121)  评论(0编辑  收藏  举报