Python写业务逻辑的几个编码原则

作为一个写业务逻辑的boy,我需要专注的就是把业务逻辑写好。写业务逻辑并不复杂,就是把编程最基础的东西使用好,有变量循环流程控制函数数据库等。
但是写出的逻辑要通俗易懂、易于理解,避免炫技、晦涩。在目前团队中待了一段时间了,根据 code review 和自己的理解整理出一些基本原则。

1|0业务代码思想原则


1|1第一:代码要足够容易阅读。


代码是给程序员阅读的,首先要做到的就是逻辑清晰,易于阅读。所以要避免毫无意义的变量名、嵌套过多的逻辑判断、过于复杂的流程控制。在易读性和性能两者之间,首先要保证易读性,当然两者并不冲突。

1|2第二:代码性能要有保证


python代码的执行速度比不上编译性语言,所以要在代码层面上保证性能的可靠。通常解决一个主要降低性能的点,就能提升整体的性能。

2|0业务代码编码原则


2|1变量


核心思想:清晰表示变量的功能
原则

  1. 变量命名统一,python推荐使用下划线分隔命名法,即蛇形命名法,毕竟python就是蛇嘛。真实原因:Python 为什么要推荐蛇形命名法
  2. 变量命名中可以带数据类型,如 buy_user_listid_to_name_dict 。python的灵活性高,为了更加方便区分变量、函数、方法等,变量名加数据类型是个好方法
  3. 超过三个的常量都要用枚举值。善用枚举值,让枚举值的名字解释常量,这是遵守第一条原则,容易阅读
  4. 多使用局部变量少使用全局变量,命名空间中局部变量优先搜索

2|2流程控制


核心思想:减少if else嵌套,逻辑越清晰越好
原则
减少if else

  1. 可以使用字典的key value特性,直接用key命中条件,避免if判断。
  2. 使用装饰器装饰函数,装饰器实现里用字典特性做if else判断。可参考:如何简化大量的 if…elif…else 代码?
  3. 用in操作在判断是否存在方面可以替换if else判断
  4. 用max,min等内置函数在判断大小方面可以替换if else
  5. 用bool可以判断出True或False,结合int(bool(object))可以在判断存在方面替换if else
  6. 使用any 或 all 将多个判断一起处理,减少if else的分支
  7. 使用发布订阅者模式,订阅者对不关心的消息选择忽略。如python 原生库的信号通信blinker python中的信号通信 blinker
  8. 使用面向对象中的多态
  9. 根据or操作的短路特性,减少if。num = False or 100

使用多态减少ifelse判断。根据传入的文件类型,保存到不同的文件中。

逻辑判断写法

class Save: def __init__(self, file_type): self.file_type = file_type def save_log(self): if self.file_type == "txt": print("txt") elif self.file_type == "tar": print("tar") elif self.file_type == "ini": print("ini") file_save = Save("tar") file_save.save_log() >>> tar file_save = Save("ini") file_save.save_log() >> ini file_save = Save("txt") file_save.save_log() >> txt

多态写法

class SaveFactory: def __init__(self, save_obj): self.save_obj = save_obj def save_log(self): self.save_obj().save_log() class Txt: def save_log(self): print("txt") class Tar: def save_log(self): print("tar") txt = SaveFactory(Txt) txt.save_log()

无法减少if else时要让逻辑清晰

  1. 使用三目运算,将if else变成一行逻辑
  2. 在函数中符合条件就return,不符合条件继续走下面流程,替换走完if else在return。可有效减少if else嵌套。
  3. 存在复杂的判断条件时,可以先将判断条件处理一遍。如一个判断(a and b) or (c and d)操作时,先单独判断出 a and b 和 c and d,然后再判断两者结果。
  4. 减少if else之间的处理流程。if或else中处理的流程过长时要尽量简化流程处理,抽象出函数。让if else对齐,处理的逻辑看起来清晰。
  5. if条件的短路特性。if a or b 这种判断中,如果a是True就不会判断b,所以将True条件写在前面可以节省判断时间。
    简单小例子:使用 all 减少 if else
have_opencourse = True if plan_id in [1,2] else False user_info = bayuser.get_user_info(user_id) register_time = pendulum.parse(user_info.created_at) register_at_today = True if register_time.date() == get_local_today() else False checkin_days = uc.get_user_checkin_days(user_id) checkin_zero_day = True if checkin_days == 0 else False ab_test_id = 414 ab_test_name = words_utils.get_user_plan(user_id, ab_test_id).user_plan no_provide = True if ab_test_name == "no_provide" else False # 使用if else判断 if register_time.date() == get_local_today() and checkin_days == 0 and ab_test_name == "no_provide" and plan_id in [1,2]: return encoder.json_response(code=200) # 使用all判断 if all([have_opencourse, register_at_today, checkin_zero_day, no_provide]): return encoder.json_response(code=200)

2|3循环


核心思想:减少for循环
原则

  1. 用for循环代替while循环,for循环比while循环快
  2. 使用隐式for循环代替显式for循环。如sum,map,filter,reduce等都是隐式for循环
  3. 尽量不要打断循环。打断循环的放在外面。有判断条件的语句和与循环不相关的操作语句尽量放在for外面
  4. 应当将最长的循环放在最内层,最短的循环放在最外层,以减少CPU跨切循环层的次数
  5. for循环和集合都可以处理的选择集合解决,集合的效率远高于循环

简单小例子:集合替代for循环

# for循环 for user in pay_user_cet4_set: if user not in all_presale_user_set: cet4_push.append(user) # 集合操作 cet4_push = pay_user_cet4_set - all_presale_user_set

2|4函数


核心思想:功能单一,短小精悍
原则

  1. 函数设计要尽量短小,嵌套层次不宜过深
  2. 一个函数只做一件事,尽量保证函数语句粒度的一致性。
  3. 函数申明应该做到合理,简单,易于使用。函数名合理,参数不宜过多。
  4. 函数参数设计应该考虑向下兼容。通过添加默认参数来实现。

3|0小结


之前分享过一本如何优雅写python的书,可以看之前写的一篇文章:
改善python程序的91个建议

在每一个开发团队都有会团队的代码风格。优秀的代码风格让团队中庞大的代码井井有条,处处有规律可循,就像是一个人完成的。每一个人也要有自己的代码原则,缺少基本原则的指导会让代码看起来不和谐,前后矛盾,这样肯定是不利于个人成长的。

本文提到的原则并见得全部正确,只是我个人在实际工作中的真实总结,绝不是闭门造车,仅供参考,欢迎交流。后续总结的原则也会继续更新到这里。


__EOF__

本文作者goldsunshine
本文链接https://www.cnblogs.com/goldsunshine/p/15694007.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   金色旭光  阅读(880)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示