跳转至

celery传参时的对象转换

前言

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

1、对象转换json

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

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

2、json转成对象

在异步任务里面又将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')]
结论就是celery的形参不能是对象。

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

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

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

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

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

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



觉得有用的老铁们可以"微信"赞助一杯82年的雪碧呦。
txtddd
本文阅读量  次

评论