职业生涯第二课---"前人埋雷,后人踩坑"

前言

在这段半个月的实习生涯中,前几天主动优化自己写的代码,还学到了分布式事物锁,有点沾沾自喜。没想到没过几天就踩到了前人埋下的雷。

正文

事情是这样的,我接手了上个实习生的工作,对原有的程序做扩展多写几个接口,有个接口需要用到高德的poi_id来获取经纬度,我发现前人已经写好了代码,我就直接粘过来用,他是将获取的经纬度作为一个列表返还。 关键代码如下

Python 复制代码
                        location_split = location.split(",")
                        if len(location_split) == 2:
                            latitude, longitude = map(float, location_split)
                            coordinates_dict[poi_id] = (latitude, longitude)

实际上开发文档

我看到他的代码后粘过来后改了一下返还了个字典,直接用他的经纬度的变量作为字典经纬度的值。QAQ 结果这个老6经度写成维度,维度写成经度。

我的这个函数在拿到经纬度后向后端发送请求,但后端接到后出现了这样的情况

省市区后端没有解析出来,因为这个接口前端偷懒了,直接将表单传给了后端,因此这个post请求的负载展开后一千多行(太抽象了QAQ),其中和位置相关的地方采用了双重转码,先将那个地方转为JSON作为值,再将整个对象再转一次JSON。

导致我看这个数据的时候一脸懵逼。 试了好多次还以为是自己的问题,然后不停地改负载,最后发现了他的位置相关信息的编码是转了两次JSON......蛮抽象的

为了转码还写了个递归函数

Python 复制代码
# 处理双重编码的JSON字符串(本接口中的地址部分的value就是双重编码)递归调用深层解码
def decode_double_encoded_json(data):
    if isinstance(data, dict):
        for key, value in data.items():
            if isinstance(value, str):
                try:
                    decoded_value = json.loads(value)
                    data[key] = decoded_value
                except json.JSONDecodeError:
                    pass
            elif isinstance(value, dict) or isinstance(value, list):
                decode_double_encoded_json(value)
            else:
                pass

然后, 就在此时,打印出相关信息进行对比时发现经纬度竟然刚好相反(下图是经纬度改正后的截图)

也就是说我之前排查错误的方向,什么JSON转码,什么字典中的str是双引号单引号都错了。 然后再测试就ok了,发现经纬度错了后就往前排查调用发现是工具函数的锅,这个bug卡了我两天了,还问了领导,到最后领导都以为是JSON转码的问题。(没敢告诉他是自己省事抄了个工具函数才踩雷的)

然后我就看他的函数的调用,结果发现他的函数的调用每次都是直接调用哪个列表,因为排序是没有错的,他从未单独用过经度或维度,所以他那个三个接口一直没有报错在正常跑着,真的我哭死。。。。。。

多线程监视器的优化

最近还有个想法,去优化我写的一个监视器 源代码关键部分如下

Python 复制代码
# 登录状态监视器,检查是否是登录状态,若是登录状态则将cookies和headers保存到全局变量中
def monitor_login():
    global cookies,headers,login_flag
    thisflag = login_flag
    while True:
        time.sleep(2)
        # 如果调用了登录接口,尝试获取cookies和headers
        if thisflag != login_flag:
            # 40s后尝试登录
            time.sleep(40)
            is_login = browser_data()
            if not is_login:
                print("当前为未登录状态,20s后重新尝试")
                time.sleep(20)
                is_login = browser_data()
                if not is_login:
                    print("当前为未登录状态,请检查")
            else:
                print("成功获取登录信息")
                time.sleep(5)

登录接口的钩子函数,用来触发监视器

Python 复制代码
# 发送登录响应后,通过修改全局变量触发监视器
@after_this_request
def post_callback_task(response):
    global login_flag
    login_flag = not login_flag
    return response

注册多线程

Python 复制代码
# 注册线程函数,启动后台线程来监控登录状态的变化
monitor_thread = threading.Thread(target=monitor_login)
# 守护进程
monitor_thread.daemon = True
monitor_thread.start()

个人感觉此监控器处于长期运转状态,会造成性能浪费。然后我就想能不能每次调用的登录接口的时候短暂唤醒这个线程,然后执行完后再进入沉睡,在调用接口时再唤醒。

优化测试

修改逻辑,只在触发函数后监控器运行一小段时间。能够节省时间。实验逻辑的测试样例如下:

Python 复制代码
pause_event = threading.Event()
def case1():
    flag =0
    while True:
        flag = flag+1
        print(flag)
        time.sleep(1)
        if flag % 5 == 0:
            # 冻结线程
            pause_event.clear()
            pause_event.wait()

# 注册线程函数,启动后台线程来监控登录状态的变化
monitor_thread = threading.Thread(target=case1)
# 守护进程
# monitor_thread.daemon = True
monitor_thread.start()
time.sleep(7)
#模拟调用接口
while True:
    x = input("请输入")
    if x == "1":
        # 触发解禁
        pause_event.set()

但将相关逻辑嫁接到项目中后主线程被阻塞。

有没有jym有好的想法和建议?

相关推荐
Eric.Lee20212 分钟前
moviepy将图片序列制作成视频并加载字幕 - python 实现
开发语言·python·音视频·moviepy·字幕视频合成·图像制作为视频
Dontla7 分钟前
vscode怎么设置anaconda python解释器(anaconda解释器、vscode解释器)
ide·vscode·python
qq_529025291 小时前
Torch.gather
python·深度学习·机器学习
数据小爬虫@1 小时前
如何高效利用Python爬虫按关键字搜索苏宁商品
开发语言·爬虫·python
Cachel wood1 小时前
python round四舍五入和decimal库精确四舍五入
java·linux·前端·数据库·vue.js·python·前端框架
終不似少年遊*1 小时前
pyecharts
python·信息可视化·数据分析·学习笔记·pyecharts·使用技巧
Python之栈1 小时前
【无标题】
数据库·python·mysql
袁袁袁袁满2 小时前
100天精通Python(爬虫篇)——第113天:‌爬虫基础模块之urllib详细教程大全
开发语言·爬虫·python·网络爬虫·爬虫实战·urllib·urllib模块教程
老大白菜2 小时前
Python 爬虫技术指南
python
古希腊掌管学习的神3 小时前
[搜广推]王树森推荐系统——矩阵补充&最近邻查找
python·算法·机器学习·矩阵