问答 自己写了段代码,感觉写的有点烂,希望大佬帮忙看看如何优化

llyyff · 2021年03月24日 · 最后由 llyyff 回复于 2021年03月26日 · 5019 次阅读

需求:我需要在测试之前创建一些分类并获取这些分类下子分类的 id 应用于其他接口。(三个父级分类和三个子级分类各创建一个)父级分类的 id 是子级分类添加时的的一个必填参数

共收到 18 条回复 时间 点赞

额,既然这是一个函数,你的需求描述是不是应该参照 leecode ,说明入参格式,出参要求,然后举个例子?

光看这段代码,不知道你入参出参的信息,代码里也没有注释说明正在做的业务逻辑是什么,没法给意见。只能说代码好长,可读性比较差。

陈恒捷 回复

对的,我就是觉得代码太长了,有点乱。。

这是新加的入参要求,出参的话会返回一个列表(子级分类 id 的列表)
例子的话:比如说我添加一个图片,请求参数有一个图片分类 id(子级分类 id),我模拟当前系统未有图片分类数据时,进行添加该图片分类,那我就需要先添加图片分类的父级分类,然后获取该父级分类的 id,然后作为参数来添加子级分类,添加子级分类完成后,返回一个子级分类的列表(len(list)=3,不会在长了,除非特殊要求),其他接口需要分类 id 时,直接取就可以了

llyyff #16 · 2021年03月24日 Author


这里是 yaml 的数据

结构写成类,获取元素写成类成员函数 get。
if 能写成 case 写成 case

llyyff #14 · 2021年03月24日 Author
magicyang 回复

好的,大佬,我去改改

ide 背景不错

llyyff 回复

python 有 case?

llyyff 回复

你这个举例和入参出参说明,还是很不清晰呀。。。

举例应该是明确给出入参长什么样的时候,出参要长什么样。你的举例只是业务逻辑说明,不是真正的例子。建议去看看 leetcode 的例子吧。

另外,从你这个逻辑上,我理解的大概伪代码:

def get_common_data(datas):
    for data in datas:
        if (data.hasKey('level') and data['level']) == 2:
            # 二级分类多加一个获取 parentId 的函数,然后把 parentId set 回 data 里面
        add_data(data)

def add_data(data):
    # 这里写具体怎么 add data 的逻辑

你代码的主要问题是,一下子把太多细节展开了,而且命名也不大好,有些没有业务含义的工具类函数命名(如get_data_from_rex),所以容易看懵逼,也容易出现各种 KeyError、数组越界之类的问题。

建议可以仿照上面写的伪代码,抽离一部分细节,主要的函数只体现业务逻辑,具体细节放到别的函数里。

llyyff #10 · 2021年03月24日 Author
陈恒捷 回复

谢谢大佬的回复 目前已经将公共模块单独摘了出来;命名的话确实有点随心所欲了,想到一个就命名一个,这点我在改改;入参出参说明我再去看看 leetcode。最后多谢大佬😀

llyyff #10 · 2021年03月24日 Author
咸鱼菜鸡 回复

这个我百度了下,好像有用字典实现类似 case 的方法😂

llyyff 回复

case 可能是指用例

llyyff #12 · 2021年03月24日 Author

应该不会是用例吧😂 。而且我这里也不会用到用例,我写这个一是为了造数据,而是为了获取 id。

llyyff 回复

我的锅,我自以为是了,以为 python 也有。。。
不要有魔法数字 “0”、“1” 之类的。
就像恒捷说的,可以去 leetcode 看看大佬的题解,有些代码真的是规范且简洁。
google、微软都有一套代码规范,我也没有耐心全看完。
慢慢写,慢慢练吧。我代码也是一堆 if,else 最多会保证没有魔法数字,嵌套低于 3 层,尽量用类,函数尽量不超过 30 行。
其他的不会太刻意的写,仅供参考。我自己 c++ 也仅仅是入门,和真正的大佬比起来,那就是个菜鸡。

llyyff 回复

也分享一下我日常写代码的大概过程,可能会更偏向于怎么让代码可读性更高,或者说怎么更清晰展示自己的逻辑思路,供参考。

1、先明确这个程序要做什么,怎么做。画个时序图啥的记录下来。一般这个时候就大概知道要分几步,每一步做什么了。然后可以根据这个时序图,一个泳道一个类/函数来拆分。
2、根据时序图拆分比较大的函数,然后代码里写上函数名字和函数文档(类似 javadoc ,按照语言规范可以自动生成文档的,idea 会自动补全,写起来不用太特意去留意格式)
3、对每个函数,写出其中会涉及逻辑的部分,比如 for 循环、if else 这些。但要留意,只写展示思路脉络的一层,很多细节(比如接口请求的具体入参啥的)先拿个函数名或者注释占着。类似伪代码先展示思路。
4、把上一步那些占位的细节补充上,补充方法可以直接写实现(实现简单且没有多处使用),或者抽离一个私有函数(实现比较复杂,里面也有不少 for 或者 if ,或者会有多处用到)。

总体上有点像写文章,先写大纲,确认大纲没问题,再细化各个章节内容。这样写的时候,每次思考的上下文会是有限范围内的内容,不会从头理到尾导致捡了芝麻丢了西瓜,函数本身也比较短小,注释相对也全(第 1、2、3 步都有各种注释或者图示),比较容易读懂。
至于调通,只要思路没大问题,调通不会太花时间。

把第二个 if 改查 else,程序就能少一次判断

llyyff #16 · 2021年03月26日 Author
magicyang 回复

魔法数字 0,1 这类的我百度看了看,现在写的正在用枚举代替,leetcode 我抽空看了看,可能是我基础太差的原因,没多少能看懂的😂 ,规范啥的我也没太看出特别不一样的。。关于 if else 我也是也一大堆。。最后多谢大佬的指点😊

gaomengsuijia 回复

好的,我去再改改,多谢大佬

llyyff #17 · 2021年03月26日 Author
陈恒捷 回复

多谢大佬的分享,我在写代码过程中确实有先写代码在考虑逻辑,等逻辑不通再修改代码等诸多问题的情况。目前正在改进,多谢大佬的指点😊

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册