关闭

python代码refine实例

907人阅读 评论(0) 收藏 举报

有段代码这么写的:

def http_request(request_url="", method="POST", data=""):
    headers = {};
    headers["Content-Type"] = "application/json;charset=utf-8";
    headers["Accept"] = "application/json";

    try:
        # TODO: never use system default block request, use eventlet instead.
        req = urllib2.Request(url=request_url, data=data, headers=headers);
        req.get_method = lambda: method;
        urllib2.socket.setdefaulttimeout(Constants.JOIN_TRANSCODER_TIMEOUT);
        response = urllib2.urlopen(req);
    except Exception, ex:
        # TODO: always this error code?
        code = Errors.join_transcoder_error;
        msg = "url=%s connection error, code=%#x, detail=%s"%(request_url, code, ex);
        Logger.error(tag, "http_request+error %s"%(msg));
        return (code, msg, Errors.parse_msg(code, msg));

    if not Constants.is_request_ok(response.code):
        code = Errors.join_transcoder_error;
        msg = "url=%s request error, code=%#x"%(request_url, code);
        Logger.error(tag, "http_request+error %s"%(msg));
        return (code, msg, Errors.parse_msg(code, msg));

    response_str = response.read();
    ret = json.loads(response_str);
    return (ret["code"], "url=%s request success"%(request_url), response_str);

做的事情很少,但是看起来超级复杂,原因在于这个函数提供了:

1. http请求的功能,包括GET/POST。

2. 错误处理:错误和具体的逻辑相关(join_transcoder_error)。

3. 混乱的错误逻辑:几个地方都判断错误,返回不同的码。

4. 混乱的返回值:试图提供直接返回给client的错误信息,应该返回定义良好的错误码。

5. 实际上这个函数只是返回了http的结果,外面还得去解析json。

会导致使用起来很奇怪:

    def join(self):
        (code, msg, response_str) = http_request(self.worker_url, "GET", data=None);
        self.error_code = code;
        if not Errors.is_success(code):
            self.reset(code);
            return code;

        ret = json.loads(response_str);
        if Constants.is_offline(ret["data"]["heartbeat_time"]):
            code = Errors.not_heartbeat_error;
            Logger.debug(self.__tag, "transcoder+join transcoder worker_id=%s, url=%s "
                "change status to offline. code=%#x"%(self.worker_id, self.worker_url, code));
            self.reset(code);
            return code;

        self.status = ret["data"]["status"];
        self.error_code = ret["code"];
        self.remain_cpu = ret["data"]["remain_cpu"];
        self.heartbeat_time = ret["data"]["heartbeat_time"];

        if ret["data"]["remain_cpu"] == 0:
            self.status = Constants.WORKER_STATUS_WORKING;

        return Errors.success;

拿到http_request之后还需要解析json,很罗嗦。


建议refine如下:

'''
perform a http get request, parse the response to json.
@param url: a str indicates the url to request.
@return tuple(code, desc, data) where:
    code: the error code, @see: Errors.
    desc: the error description str.
    data: parsed response object in json. None if error.
'''
def http_get(url):
    (code, desc, data) = (Errors.success, "success", None);

    try:
        res = eventlet.green.urllib2.urlopen(url=str(url)).read();
    except Exception, ex:
        code = Errors.network_http_get;
        desc = "http get error, url=%s, code=%#x, exception=%s"%(url, code, ex);
        Logger.error(tag, "http_request+error %s"%(desc));
        return (code, desc, data);

    try:
        data = json.loads(res);
    except Exception, ex:
        code = Errors.network_json_parse;
        desc = "parse json error, url=%s, code=%#x, res=%s, exception=%s"%(url, code, res, ex);
        Logger.error(tag, "http_request+error %s"%(desc));
        return (code, desc, data);

    return (code, desc, data);

这个函数分开了GET和POST,对结果解析为JSON。调用如下:

    def join(self):
        (code, desc, data) = bravo_utility.http_get(self.worker_url);
        self.error_code = code;
        if not Errors.is_success(code):
            self.reset(code);
            return code;

        self.status = data["data"]["status"];
        self.error_code = data["code"];
        self.remain_cpu = data["data"]["remain_cpu"];
        self.heartbeat_time = data["data"]["heartbeat_time"];

        if data["data"]["remain_cpu"] == 0:
            self.status = Constants.WORKER_STATUS_WORKING;

        return Errors.success;

当然,还有更好的做法,但这样改已经有所进步了。

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:544533次
    • 积分:8019
    • 等级:
    • 排名:第2643名
    • 原创:250篇
    • 转载:11篇
    • 译文:12篇
    • 评论:276条
    文章分类
    最新评论