编码规范

1 Matlab编码规范

1.1 命名规则

1.1.1 变量
  • 小驼峰命名法
    • 第一个单词以小写字母开始,后面单词的首字母大写。例如:firstNamelastName
  • 使用英文
    • 变量名最重要的原则就是,一看就知道这个变量是什么意思。
  • 大范围的变量应带有意义的名称,小范围变量可用短变量名(无意义)
    • 例如:stepSize:大范围意义、dt(δt):小范围。
  • 循环变量
    • 应该以ijk为前缀。例如:iFilesjPositions。不使用ij的原因是:这两个在matlab中是虚数。
    • 此外常用循环变量还有:numitercountmarkindexid以及这些循环变量的组合形式。
  • 代表单个实体数据的变量可以加以后缀No
    • 例如:tableNoemployeeNo
  • 避免否定式的布尔变量命名
    • 例如:若命名isNotFound,在使用判断的时候,~isNotFound,搞半天才知道啥意思。所以不适用否定式布尔变量命名。
  • 拓展变量
    • 释义:就是在已有变量上经过进一步计算得到的新变量,或者与已有变量相关的变量。
    • 策略1:在已有变量的基础上以小驼峰命名的方法在变量的后端添加限定词;
    • 策略2:在已有变量的基础上以小驼峰命名的方法在变量的前端添加限定词;
    • 推荐使用默认使用——策略1。

参考链接1:程序员如何优雅地对变量命名?- idea小时的文章 - 知乎
参考链接2:变量命名规范

1.1.2 常数
  • 全大写字母+下划线
    • 例如:MAX_ITERATIONSCOLOR_RED
  • 参数可以以某些通用类型名作为前缀
    • 例如:COLOR_REDCOLOR_GREENCOLOR_BLUE
1.1.3 结构体
  • 大驼峰命名法
    • 这是区别一般变量,例如:ParameterSet
  • 结构体的命名应该是隐性的,并且不需要包括字段名
    • 例如:用Segment.length,避免Segment.segmentLength
1.1.4 函数
  • 函数名应该采用全小写字母+下划线
  • 函数名与它的.m文件名必须相同
  • 函数名应该有具体的意义
    • 避免短的函数名/缩写,这经常使得其名字含糊不清。
    • 例如:采用:compute_total_width(),避免:compwid()
  • 避免无意识地覆盖
    • 有时候我们取的名字,可能在MATLAB中含有这个函数名了,可以用exist检查是否含有了。

1.2 文件与程序结构

1.2.1 .M文件
  • 模块化

    • 编写一个大程序的最好的方法是将它以好的设计分化为小块(通常采用函数的方式)。
    • 这种方式通过减少为了理解代码的作用而必须阅读的代码数量使得程序的可读性、易于理解性和可测试性得到了增强。超过编辑器两屏幕的代码都应该考虑进行分割。并且设计规划很好的函数也使得它在其他的应用中可用性增强了。
  • 确保交互过程清晰

    • 函数通过输入输出参数以及全局变量与其他代码交互通信。使用参数几乎总是比使用全局变量清楚明了。采用结构体可以避免那种一长串儿的输入输出参数的形式。
  • 分割与封装

    • 所有的子函数和所有的函数都应只把一件事情做好。每个函数应该隐藏(hide)一些东西。
    • 任何在多个.m文件中出现的代码块都应该考虑用函数的形式封装起来。
  • 利用现有的函数

    • 开发一个有正确功能的、可读的、合理灵活性的函数是一项有重大意义的任务。或许寻找一个现成的提供了要求的部分、甚至全部功能的函数应该更快也更具有正确性。
  • 子函数

    • 只被另外一个函数调用的函数应该作为一个子函数写在同一个文件中。这使得代码更加利于理解与维护。
  • 测试脚本

    • 为每一个函数写一个测试脚本。这样可以提高初期版本的质量和改进版本的可靠性。

1.3 注释、文档与排版

1.3.1 注释

注释的目的是为代码增加信息。注释的典型应用是解释用法、提供参考信息、证明结果、阐述需要的改进等。经验表明,在写代码的同时就加上注释比后来再补充注释要好。

  • 注释文字应该简洁易读
    • 一个糟糕的或者是无用的注释反而会影响读者的正常理解。N.Schryer提到:“如果代码与注释不一致,那么或许两者都是错误的。”
    • 一个通常更重要的是注释应该讲的是“为什么(Why)”和“怎么做(how)“,而不是“是什么(what)”。
  • 函数的注释写法(英文好的话尽量使用英文)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
%================================================================
% 功能: 传统LMS滤波算法
% 输入参数:
% xn 输入信号
% mu 步长因子
% dn 参考信号
% numIte 迭代次数
% M 滤波器阶数
% 输出参数:
% theta 滤波器的系数矩阵
% en 误差信号
% yn 滤波器的输出信号
% 备注: 入射角只考虑一个维度的
% 调用方法: 见XXX文件
% 日期: 2011/7/12 20:37
%================================================================

function [theta,en,yn] = my_lms(un, dn, mu, Num_iteration, M)
。。。(具体编程开始)
end
1
2
3
4
5
6
7
8
9
10
11
12
13
14
%================================================================
% 功能: 求圆孔的夫琅禾费衍射光强分布
% 参数: CircleHoleFD为圆孔结构体,包含圆孔衍射相关信息;
% theta为衍射场的次波方向,可以为向量,求取各方向的光强
% 返回值: I为衍射光强分布
% 主要思路:使用夫琅禾费单缝衍射公式计算
% 备注: 入射角只考虑一个维度的
% 调用方法:见CalcCircleHoleFD_Test文件
% 日期: 2011/7/12 20:37
%================================================================

function I = calcCircleholefd(circleHoleFD, theta)
。。。(具体编程开始)
end
  • 一段代码注释写法
    • 用于理解一小段代码含义的注释,统一写在代码上方,如:
1
2
3
4
5
%(1)初始化 
Number = zeros(1,PNumber);
for i = 1:PNumber
Number(i) = MNumber;
end
  • 一句代码注释写法
    • 用于理解一句代码的意思可以写在代码后方,但是注意不能超过180字符。太长可以考虑写在代码上方,如:
1
2
3
4
5
gen = 0;  %迭代计数器 
JmNumber = Max_Cell(Jm); % 调用Max_Cell子函数求机器的数量
[PNumber,MNumber] = size(Jm); % PNumber为工件个数,MNumber为工序个数
trace = zeros(2, MAXGEN); % 寻优结果的初始值,一行存放各代的最优解,一行存放各代解的均值
TotalOP_Number = PNumber*MNumber; % 工序总个数
1.3.2 文档
  • 文档规范化
    • 作为有用的文档应该包含一个对如下内容的可读性的描述:代码打算干什么(要求),它是如何工作的(设计),它依赖于什其他什么函数以及怎么被其他代码调用(接口),以及它是如何测试的等。对于额外的考虑,文档可以包含解决方案的选择性的讨论以及扩展与维护的建议。
  • 首先考虑书写文档

    • 一些程序员相信的方法是:“代码第一,回答问题是以后的事情。”而通过经验,我们绝大多数人知道先开发设计然后再实现可以导致更加满意的结果。如果将测试与文档留在最后,那么开发项目几乎不能够按期完成的。首先书写文档可以确保其按时完成甚至可能减少开发时间。
  • 修改

    • 一个专业的对代码修改进行管理和写文档的方法是采用源程序控制工具。对于很简单的工程,在函数文件的注释中加入修改历史比什么都不做要好。
1.3.3 排版
  • 空格的使用
    • 在二元运算符两边各空一格[=, -, +=, ==, >, in, is not, and];
    • 函数的参数列表中,,之后要有空格;
    • 函数的参数列表中,默认值等号两边不要添加空格;
    • 左括号之后,右括号之前不要加多余的空格;
    • 不要为对齐赋值语句而使用的额外空格

本文转自:何亮科学网博客。

链接地址:一些MATLAB的编程规范总结1.0版

其他参考链接:

科研小技巧——MATLAB的编码规范 - 西涯先生的文章 - 知乎

matlab 编程之代码规范 -枯荣有常的文章 - CSDN

MATLAB编程规范 - magic_yu42的文章 - CSDN

1.3.4 绘图、字体设置

王老师关于绘图、字体设置的一些简单设置:PlotCurvesFontSizeFontName.m

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
%% MATLAB曲线图示例设置字号字体

clear all; clc; close all;
%% Lena512.bmp图像
%% X Y分别为编码比特率和峰值信噪比
X1=[0.15 0.20 0.25 0.30 0.40 0.50 0.60 0.75 1.00 1.25];
X2=X1; X3=X1; X4=X1;
Y1=[22.0370 23.4718 24.3595 25.1125 26.5516 27.8992 29.1981 30.8826 33.2239 35.0960];
Y2=[22.5249 23.5379 24.2606 24.9596 26.3507 27.5956 28.7035 30.0974 32.1077 33.7383];
Y3=[22.5594 23.6605 24.3931 25.1403 26.5922 27.8500 28.9936 30.4864 32.5300 34.1851];
Y4=[22.6049 23.7881 24.6194 25.4626 27.0361 28.3933 29.6686 31.3865 33.5905 35.3823];
plot(X1, Y1, '- r .', X2, Y2, '-. b o', X3, Y3, ': m *', X4, Y4, '-- k p', 'LineWidth', 1)
legend('DCT-JPEG', 'APWBT-JPEG', 'APDCBT-JPEG', 'APIDCBT-JPEG')
axis([0, 1.4, 22, 36]);
%% MATLAB的默认字体是Helvetica,fontname的设置,中文字体:宋体、楷体、仿宋、隶书、微软雅黑、幼圆等
%% 英文字体: Times New Roman, Arial, Bodoni, Calibri, Courier New, Frutiger, Futura, Garamond, Geogia, Platino Linotype, Verdana等
xlabel('\fontsize{12}\fontname{宋体}码率\fontname{Times New Roman}(bpp)')
ylabel('\fontsize{12}\fontname{Times New Roman}PSNR (dB)')
set(gca, 'xtick', [0:0.2:1.4], 'ytick', [22:2:36], 'FontSize', 12, 'Fontname', 'Times New Roman');

2 Python编码规范

2.1 编码

无特殊情况,建议Python脚本程序一律使用 UTF-8 编码,并且在文件头部必须加入#-*-coding:utf-8-*-标识,声明文件编码方式,程序文件编码要和声明编码保持一致。

2.2 命名规范

文件/模块

  1. 小写字母,使用下划线:Python 的文件名通常是小写字母,单词之间使用下划线 (_) 来分隔。例如:my_script.pyhello_world.py
  2. 避免使用大写字母:Python 不推荐在文件名中使用大写字母。虽然操作系统允许使用,但遵循小写字母的规范可以增加代码的可读性和一致性。
  3. 避免特殊字符和空格:尽量避免在文件名中使用特殊字符(如 !, @, #, &, 空格等)。使用下划线来分隔单词。

python中,一个python文件(以.py为后缀名的文件)就叫作模块,每一个模块在python里都被看做是一个独立的文件。 使用模块也可以避免函数名称和变量名称重复,在不同的模块中可以存在相同名字的函数名和变量名。

简单了解一下python中模块、库、包之间的概念差异

  • 模块(module)其实就是py文件,里面定义了一些函数、类、变量等
  • 包(package)是多个模块的聚合体形成的文件夹,里面可以是多个py文件,也可以嵌套文件夹
  • 库是参考其他编程语言的说法,是指完成一定功能的代码集合,在python中的形式就是模块和包

我们简单地将这三者都统称为模块,因为我们只需要知道如何去使用就可以了

类名: 类名使用驼峰(CamelCase)命名风格,首字母大写,私有类可用一个下划线开头;将相关的类和顶级函数放在同一个模块里。不像Java,没必要限制一个类一个模块。

1
2
3
4
5
6
7
8
9
class Farm():
pass

class AnimalFarm(Farm):
pass

class _PrivateFarm(Farm):
pass

函数名:

函数名一律小写,如有多个单词,用下划线隔开;如果要定义私有函数,可以在函数名前面加一个下划线。

1
2
3
4
5
def run():
pass

def run_with_env():
pass

变量名

  • 变量名尽量小写,如有多个单词,用下划线隔开;
1
2
3
if __name__ == '__main__':
count = 0
school_name = ''
  • 常量采用全大写,如有多个单词,使用下划线隔开;
1
2
3
MAX_CLIENT = 100
MAX_CONNECTION = 1000
CONNECTION_TIMEOUT = 600
特性 Python Java
文件命名 hello_world.py(小写字母+下划线)
函数命名 run_with_env()(小写字母+下划线)
变量命名 snake_case(小写字母+下划线) camelCase(首字母小写驼峰命名)
类名命名 CamelCase(大写字母开头的驼峰命名) amelCase(大写字母开头的驼峰命名)
常量命名 UPPER_CASE(全大写字母+下划线) UPPER_CASE(全大写字母+下划线)
私有变量 使用单下划线_var 或双下划线 __var 使用 private 关键字

【参考资料1】:002.Python命名规则

【参考资料2】:【Python】编程代码书写规范!- 科皮子菊的文章 - CSDN

【参考资料3】:PEP8中文版 — Python编码风格指南

2.3 注释

  • 行注释:# 开头,# 右边的所有内容都被当做说明文字,只起到辅助说明作用。
1
print("hello python")  # 输出 `hello python`

注:为了保证代码的可读性,# 后面建议先添加一个空格,然后再编写相应的说明文字。

  • 多行注释(块注释)#号后空一格,段落件用空行分开(同样需要“#”号)。
    • 如果希望编写的 注释信息很多,一行无法显示,就可以使用多行注释。
    • 要在 Python 程序中使用多行注释,可以用 一对连续的 三个引号(单引号和双引号都可以)。
1
2
3
4
5
6
"""
这是一个多行注释;
......
在多行注释之间,可以写很多很多的内容
"""
print("hello python")

补充: 什么时候需要使用注释?

1、 注释不是越多越好,对于一目了然的代码,不需要添加注释;
2、 对于复杂的操作,应该在操作开始前写上若干行注释;
3、 对于不是一目了然的代码,应在其行尾添加注释(为了提高可读性,注释应该至少离开代码 2 个空格)。

2.4 空格使用

  • 在二元运算符两边各空一格[=, -, +=, ==, >, in, is not, and]

  • 函数的参数列表中,,之后要有空格

  • 函数的参数列表中,默认值等号两边不要添加空格
  • 左括号之后,右括号之前不要加多余的空格
  • 字典对象的左括号之前不要多余的空格
  • 不要为对齐赋值语句而使用的额外空格

2.5 文档注释docstrings

文档注释,用于解释文档程序,帮助你的程序文档更加简单易懂。docstring 的规范中最其本的两点:

  • 所有的公共模块、函数、类、方法,都应该写 docstring 。私有方法不一定需要,但应该在 def 后提供一个块注释来说明。
  • docstring 的结束"""应该独占一行,除非此 docstring 只有一行。
1
2
3
4
5
"""Return a foobar
Optional plotz says to frobnicate the bizbaz first.
"""

"""Oneline docstring"""

补充: 作为文档的Docstring一般出现在模块头部、函数和类的头部,这样在python中可以通过对象的__doc__对象获取文档,编辑器和IDE也可以根据Docstring给出自动提示。

  • 文档注释以"""开头和结尾, 首行不换行, 如有多行, 末行必需换行, 以下是Google的docstring风格示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# -*- coding: utf-8 -*-
"""Example docstrings.

This module demonstrates documentation as specified by the `Google Python
Style Guide`_. Docstrings may extend over multiple lines. Sections are created
with a section header and a colon followed by a block of indented text.

Example:
Examples can be given using either the ``Example`` or ``Examples``
sections. Sections support any reStructuredText formatting, including
literal blocks::

$ python example_google.py

Section breaks are created by resuming unindented text. Section breaks
are also implicitly created anytime a new section starts.
"""
  • 不要在文档注释复制函数定义原型,而是具体描述其具体内容,解释具体参数和返回值等
1
2
3
4
5
6
7
8
9
#  不推荐的写法(不要写函数原型等废话)
def function(a, b):
"""function(a, b) -> list"""
... ...

# 正确的写法
def function(a, b):
"""计算并返回a到b范围内数据的平均值"""
... ...
  • 对函数参数、返回值等的说明采用numpy标准,如下所示
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
def func(arg1, arg2):
"""在这里写函数的一句话总结(如: 计算平均值).

这里是具体描述.

参数
----------
arg1 : int
arg1的具体描述
arg2 : int
arg2的具体描述

返回值
-------
int
返回值的具体描述

参看
--------
otherfunc : 其它关联函数等...

示例
--------
示例使用doctest格式, 在`>>>`后的代码可以被文档测试工具作为测试用例自动运行

>>> a=[1,2,3]
>>> print [x + 3 for x in a]
[4, 5, 6]
"""
  • 文档注释不限于中英文, 但不要中英文混用
  • 文档注释不是越长越好, 通常一两句话能把情况说清楚即可
  • 模块、公有类、公有方法, 能写文档注释的, 应该尽量写文档注释

2.6 __doc__属性的使用

2.6.1 引言

在Python中,每个对象都有一些特殊的属性和方法,这些特殊的属性和方法可以让我们更方便地使用和理解对象。其中一个特殊的属性是__doc__属性。__doc__属性是一个字符串,用于存储对象的文档字符串。它可以帮助我们更好地理解对象的功能和使用方法。

2.6.2 什么是文档字符串

在介绍__doc__属性之前,我们先来了解一下什么是文档字符串。文档字符串是一个对象的描述信息,它用于解释对象的功能和使用方法。文档字符串通常被放置在对象的定义之后,使用三个引号(‘’’)或三个双引号(“””)括起来。下面是一个函数的例子:

1
2
3
def add(a, b):
"""This function takes two numbers as input and returns their sum."""
return a + b

在上面的例子中,函数add的文档字符串是”This function takes two numbers as input and returns their sum.”。文档字符串可以包含多行,通常用于描述函数的输入、输出和功能等信息。

2.6.3 __doc__属性的使用方法

__doc__属性是一个对象的内置属性,用于存储对象的文档字符串。我们可以通过访问对象的__doc__属性来获取其文档字符串。下面是一些使用__doc__属性的示例。

  • 获取函数的文档字符串

在Python中,我们可以通过函数名.__doc__的方式来获取函数的文档字符串。下面是一个示例:

1
2
3
4
5
def add(a, b):
"""This function takes two numbers as input and returns their sum."""
return a + b

print(add.__doc__)

运行上面的代码,输出结果为:“This function takes two numbers as input and returns their sum.”。

  • 获取类的文档字符串

类也可以有文档字符串,我们可以通过类名.__doc__的方式来获取类的文档字符串。下面是一个示例:

1
2
3
4
5
6
7
class Rectangle:
"""This class represents a rectangle."""
def __init__(self, width, height):
self.width = width
self.height = height

print(Rectangle.__doc__)

运行上面的代码,输出结果为:“This class represents a rectangle.”。

  • 获取模块的文档字符串

模块也可以有文档字符串,我们可以通过模块名.__doc__的方式来获取模块的文档字符串。下面是一个示例:

1
2
3
4
5
6
7
8
9
# rectangle.py
"""This module provides a Rectangle class."""
class Rectangle:
"""This class represents a rectangle."""
def __init__(self, width, height):
self.width = width
self.height = height

print(__doc__)

运行上面的代码,输出结果为:“This module provides a Rectangle class.”。

转载于:Python内置类属性__doc__属性的使用教程 - CSDN

3 代码整洁

https://www.cnblogs.com/bndong/tag/%E4%BB%A3%E7%A0%81%E6%95%B4%E6%B4%81/

  • Copyrights © 2015-2025 wjh
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信