管理标准 Q/ZR
中兴软创科技股份有限公司企业标准
Q/ZR GJ 04.002.1-2016




ZSmart OCS Python脚本编写规范
V1.3








2016-11-14发布 2016-11-14实施

前 言
本文规定了ZSmart OCS Python脚本编写规范。


本文件评审、修正记录

文件名称 数据库模型设计及脚本管理流程
序号 流程 拟制人/审核人 拟制/审核时间 版本号
1 编写 王宗旺 2016/11/14 V1.0
2 更新,补充python版本说明 王宗旺 2016/11/21 V1.1
3 更新,禁止使用eval函数。 王宗旺 2017/09/29 V1.2
4 目录结构的格式更新 房月明 2021/08/30
V1.3






















目 录
1. 编写目的
2. 适用范围
3. 定义、缩写词及术语
4. ZSmart OCS python脚本编写规范
4.1 格式
4.1.1 使用冒号(:)和代码缩进形式定义语句块
4.1.2 不允许单行有多个表达式
4.1.3 首行使用空格缩进
4.1.4 每级缩进使用四个空格符号
4.1.5 需对函数返回值做判断
4.1.6 变量名须有意义
4.1.7 使用GetAttrEx()函数取代GetAttr()函数
4.1.8 增加参数需向下兼容
4.1.9 Python脚本取当前时间必须使用属性3
4.1.10 使用打印日志代替抛异常
4.2 Python效率
4.2.1 使用空行分割代码块以增强可读性
4.2.2 注解行以”#”加若干空格开始
4.2.3 单行长度不超过120个字符
4.2.4 使用內建函数(abs, len, int等)
4.2.5 使用join()函数
4.2.6 合并判断条件
4.2.7 使用CODE而不用ID
4.2.8 适度的print操作
4.2.9 禁止使用eval函数
4.3 注意项
4.3.1 禁止使用中文注解
4.3.2 常量名全部大写
4.3.3 变量名全部小写
4.3.4 函数名全部小写
4.3.5 禁止在python中使用import
4.3.6 禁止调用sys.exit()函数退出

1. 编写目的

本文用于描述Python脚本通用规范和ZSmart资费脚本使用规范。

2. 适用范围

本规范适用于基于Python 2.7脚本的编写和使用,此类脚本用于ZSmart资费和充值订购赠送相关的计算和处理,ZSmart OCS/cvBS产品(包含V7和V8系列)目前建议使用Python 2.7版本。

3. 定义、缩写词及术语

专用的术语、定义见下表:

术语/定义 英文 说明
python python 脚本语言

表一 术语与定义

4. ZSmart OCS python脚本编写规范

4.1 格式

4.1.1 使用冒号(:)和代码缩进形式定义语句块

如:
def main(r):
eff_time = r.event.GetAttr(SERVICE_EFF_DATE).AsString()
*人工检查

4.1.2 不允许单行有多个表达式

一行只能表达一个含义。
如:
new_flag=’A’
term_flag=’A’
normal_flag=’A’
单行内有多个语句时,须用分号(;)隔开,比如:
new_flag=’A’; term_flag=’A’; normal_flag=’A’
*工具检查:不能出现分号

4.1.3 首行使用空格缩进

行首使用前导空格缩进,不使用tab,禁止tab和空格混用。
正确:
eff_time = r.event.GetAttrEx(SERVICE_EFF_DATE).AsString()
*工具检查

4.1.4 每级缩进使用四个空格符号

比如:
if(created_date >= cycle_begin_time and created_date <= cycle_end_time):
if(new_flag == “N”): # not charge
charge = 0
elif(new_flag == “A”): # charge per day
d1 = diffdays(cycle_end_time,completed_date)
charge = d1 price_day
else: # charge per cycle
charge = price_cycle
人工检查

4.1.5 需对函数返回值做判断

所有的变量作为函数返回值,需要添加有效性判断。
【添加说明】
eff_time = r.event.GetAttrEx(SERVICE_EFF_DATE).AsString()
if(eff_time …)
elif (eff_time …)
else
由于GetAttrEx等函数返回的字符串不一定是标准的格式,在找不到数据等情况下,会输出非标准的数据格式,脚本需要做一个有效性判断,才能继续用于逻辑判断和业务处理。有项目现场的python脚本中调用GetProdCompletedDate函数返回了NULL,而未做出错处理,直接用这个返回值调用diffdays导致了业务进程core。
工具检查

4.1.6 变量名须有意义

变量必须有含义,长度要简洁,建议不要超过20个字符。
*人工检查

4.1.7 使用GetAttrEx()函数取代GetAttr()函数

新版本的OCS/cvBS不再使用GetAttr()函数,建议使用GetAttrEx()函数获取相关参数。
*工具检查

4.1.8 增加参数需向下兼容

开发为已有的Python函数增加参数的时候,必须要保证向下兼容,不设置参数的时候逻辑和之前相同。
*产品开发规范

4.1.9 Python脚本取当前时间必须使用属性3

一些代码中向915属性中填写的时间不正确,导致从扩展属性915中获取当前时间错误。
*人工检查

4.1.10 使用打印日志代替抛异常

资费的python脚本不能抛异常,资费中的python脚本使用打印输出告警日志代替异常。
*工具检查

4.2 Python效率

4.2.1 使用空行分割代码块以增强可读性

代码过多的时候建议分块,每块不宜超过10行。
代码块的首行需要有注解,说明本代码块的功能。
*人工检查

4.2.2 注解行以”#”加若干空格开始

注释必须保存在表达式上一行,和下一行代码对齐。
比如:
# This python is used for topup reward
*工具检查

4.2.3 单行长度不超过120个字符

行末注解使用”#”加若干空格开始,并与前面的语句间有空格隔离。
不建议的注释方式:
billingcycleid = r.event.GetAttr(BILLING_CYCLE_ID).AsInteger() # get current billing cycle id
建议改为:
# get current billing cycle id
billingcycleid = r.event.GetAttr(BILLING_CYCLE_ID).AsInteger()
*工具检查

4.2.4 使用內建函数(abs, len, int等)

建议使用内建函数(abs,len,int等)代替自己编写的函数提升性能
在字符串处理和时间等运算中,优先使用python内置的函数
*人工检查

4.2.5 使用join()函数

建议使用join()函数代替+连接字符串提升性能
*人工检查

4.2.6 合并判断条件

建议在条件判断中使用”in”代替“or”和“else”,合并判断,提升性能
推荐:
if(-res in(0,3600,14500,24800,33000,35000,55500,78600,111100,200000,300000)):
res=0
不推荐:
if(-res==0 or –res==3600 or –res==14500):
res=0
elseif(-res==14500 or -res==24800 or -res==33000):
res=0
*人工检查

4.2.7 使用CODE而不用ID

直接使用ID可读性不好,不易维护,建议使用编码代替ID,比如EVENT_BEGIN_TIME代替3,BILLING_CYCLE_ID代替22,这样可读性更好一些。如果必须使用ID,必须注释说明含义和来源。
正确:
billingcycleid = r.event.GetAttrEx(BILLING_CYCLE_ID).AsInteger()
错误:
billingcycleid = r.event.GetAttrEx(22).AsInteger()
*人工检查

4.2.8 适度的print操作

建议适度的print操作
项目在调试阶段会调用print和printlog()打印日志,性能测试表明PYTHON中是否有Print语句有5%的性能差异,所以建议在上线后屏蔽一些print操作,只保留必要的信息,生产环境的print操作建议不超过5行。
*工具检查

4.2.9 禁止使用eval函数

我们的python脚本习惯使用eval函数来获取916属性, 而eval函数也是通过动态构造class来实现,项目在某些场景下使用python的eval函数获取计算结果,导致产生大量动态class,gc耗时增加,从而导致ussd订购超时。
实验证明gc耗时的增长与eval函数有关,建议通过java来实现,避免使用eval函数。
*工具检查

4.3 注意项

4.3.1 禁止使用中文注解

比如以下的注解不符合规范:
# This python is used for topup reward,支持V7.3a版本
*工具检查

4.3.2 常量名全部大写

常量名所有字母大写,由下划线连接各个单词,严禁大小写混用
*人工检查

4.3.3 变量名全部小写

变量名全部小写,由下划线连接各个单词,严禁大小写混用
正确:
prod_state = r.event.GetAttr(PROD_STATE).AsString()
错误:
Prod_State = r.event.GetAttr(PROD_STATE).AsString()
*人工检查

4.3.4 函数名全部小写

函数名全部小写,由下划线连接各个单词,严禁大小写混用(同变量名)
*产品开发规范

4.3.5 禁止在python中使用import

禁止在python中使用import,如有需要提单给开发处理
有项目现场配置的Python脚本导入sys库,遇到异常数据时直接exit导致进程退出。还有项目导入time库调用strptime,difftime等函数用于处理时间运算和格式转换,导致递归死循环。原则上现场的python脚本不应该import,可在前台界面上增加关键字检测。
*工具检查:不允许出现import

4.3.6 禁止调用sys.exit()函数退出

不能调用sys.exit()函数退出,sys模块的exit()函数会导致业务进程退出
*工具检查

4.3.7 所有新版本需要兼容老版本的函数

Python函数理论上应该是需要向下兼容,从v70升级到v73,从v73升级到v81,python脚本不能直接到新版本使用,主要就是这两个版本的python脚本有些属性ID、函数等变化,导致现场要修改相关的Python脚本,增加割接难度和错误几率,升级工作量太大。
*立项结项评审