点击上方“潜心的Python小屋”关注我们,第一时间推送优质文章。

前言
大家好,我是潜心。这段时间我看过好几位粉丝甚至是我同学(反正也看不到)写的代码,emmm,确实看得让我有点难受。好的代码规范也能体现出一位代码编写者的编程素质。所以潜心准备写一篇番外篇,介绍下Python中的代码规范(分享自己的一些代码编写习惯)。
本文约2.1k字,预计阅读15分钟。
整体代码规范
这部分不知道怎么叙述,通过举例子来说明吧。此处使用「PyCharm」IDE,因为更能凸显一些不规范的习惯。
有些同学的代码可能是这样呈现的:

这些波浪线是不是很难受?不能这样写呀,变量定义、赋值,操作符的「两端需要有空格呀」!其中命名稍微有点问题(这里不作讨论),括号也不需要,改过之后是这样的:

这样是不是更清楚点?除了上述所说,函数中变量赋值时逗号后需要一个空格:
data = pd.read_csv('ml-1m/ratings.dat',
sep='::', engine='python',
names=['UserId', 'MovieId', 'Rating', 'Timestamp'])
当然上述说的两端需要空格并不适用在为函数的参数赋值时,这里不需要加空格,如下(随便选取的一段代码):
self.MLP_Embedding_User = keras.layers.Embedding(
input_dim=num_users,
output_dim=int(layers[0] / 2),
name='user_embedding',
embeddings_initializer='random_uniform',
embeddings_regularizer=regularizers.l2(reg_layers[0])
)
另外 「导入包与函数或类需要空两行」,「函数与函数之间需要空两行」,「类中方法之间空一行」,「注释#号后需要空一格」,如下:
from utils import *
from evaluate import *
class UserCF:
"""
User-based collaborative filtering
"""
def __init__(self, train, W):
# AAA
def recommend(self, user):
def main():
命名
然后是关于命名,包括常量命名、变量命名、函数命名、类命名、方法命名等。
Python需要遵守的基本命名规则为:
命名只能包含字母、数字和下划线,但开头不能以数字命名,如可命名
message_1,不可1_message;命名不能包含空格;
不要将Python关键字、保留字和内置函数名用于命名;
上述是「最基本的命名规范」,遵守这三条规则,至少不会让你的程序因为命名问题报错。
命名准则
接下来潜心会分享一些约定俗成的命名准则,主要遵循这几个要求:
准确:名字与意义匹配易于区别。
简洁:命名长度不要过长,要简短;
明确:一个概念对应一个词,不用双关语;
关于准确,不用多说,得说明这个变量(函数等)的实际意义、作用是什么。
例如:命名用户、物品两个变量,一些同学可能会这样写:
a, b = ['u1', 'u2', 'u3'], ['i1', 'i2', 'i3']
# 或者
yonghu, wupin = ['u1', 'u2', 'u3'], ['i1', 'i2', 'i3']
其实这样命名可能对你的整个代码运行的准确率没有影响,但是你要是以后再回过去看自己代码,或让别人阅读你的代码呢(a,b到底指什么呀)?关于用中文拼音,虽然能达到「准确」的要求,但是潜心不推荐,因为这也太难受了,而且给人一种小白的感觉,今天还看到有公众号粉丝给我发的一个代码,某博客上这样命名(刚好当作反例):
def shuzizhuandaxiejine(data):
emmm,还是希望大家采用英文命名,上述问题我倾向于这样写:
user, item = ['u1', 'u2', 'u3'], ['i1', 'i2', 'i3']
接下来是简洁,潜心不建议用一个很长的英文命名,虽然「准确」,但是太长影响观感,而且有时候会因为其需要不必要的换行。
例如:定义一个基于物品的协同过滤算法,一些同学可能这样写:
class Item_collaborative_filtering:
这样太过冗长,建议这样写:
class ItemCF:
因为CF在推荐领域中,就是指代协同过滤,不需要使用完整的名称,此处需要同学们综合考虑了。
最后是明确,需要在一个Project中规范每个变量的名称,不要在一个函数中使用的变量名称,在另一个函数中又是另一个含义。
例如:在整个协同过滤的算法中,某个函数需要用户的整个列表,某个函数需要某个用户,有同学可能这样写:
def userSimilarity(user):
def recommend(user):
这样写是有歧义的,两个user,指代的内容不同。推荐这样写:
def userSimilarity(user):
def recommend(u):
或者:
def userSimilarity(user_l):
def recommend(user):
上述都是一些结合实际要求的命名,万一这个变量没有什么实际含义呢?这里有些小建议,对于数字,一般会命名为:num1, num2, ...,如果是一个数字列表:nums, arr,字符串:s1, s2,...等。
常用的命名方法
「骆驼式命名法」:正如它的名称所表示的那样,是指混合使用大小写字母来构成变量和函数的名字。函数名中的每一个逻辑断点都有一个大写字母来标记,首字母为小写。例如,下面是分别用骆驼式命名法命名:
def userSimilarity(user):
「下划线命名法」:下划线法是随着C语言的出现流行起来的。例如:
def user_similarity(user):
「帕斯卡(pascal)命名法」:与骆驼命名法类似。只不过骆驼命名法是首字母小写,而帕斯卡命名法是首字母大写,如:
def UserSimilarity(user):
一般我会选择使用下划线命名法。
其他
一些特殊的命名规则:
1、一些全局常量,建议用全部大写来命名:类似MAX_INT;
2、类名称首字母建议大写,函数、方法名称建议小写;
3、文件名称建议大写。文件名称在代码中尽量不要重复用到,有时候会出现一些错误(潜心遇到过);
注释
注释在程序中也是非常重要的一部分,虽然它不影响程序的运行,但是可以让其他用户更容易的理解你的思想。注释最好也是用英文,当然中文注释也未尝不可(不推荐主要是有些编码方式会使中文乱码)。这里潜心会通过一个以前写的代码简单介绍下自己的注释习惯。
开头
在每一个Project最开始的地方,潜心都会打上注释,标记编写项目名称、时间以及作者。例如:
"""
Created on Mar 19, 2020
Item-based collaborative filtering
@author: Qianxin
"""
这样是不是一下子觉得自己的代码厉害了起来呢?(时间是提醒你,看看上次是啥时候写的了!!!)
类
每个类下也会标注这是什么类(这里就偷懒写的比较简单):
class ItemCF:
"""
Item-based collaborative filtering
"""
类的初始化,第一行注明这是个初始化方法,参数注释有严格的要求,:param后加上参数名,再注明参数的含义。初始化和函数与类的方法注释有所不同(返回值不用写):
def __init__(self, train, W):
"""
init
:param train: train dataset
:param W: item's similarity matrix
"""
self.train = train
self.W = W
函数/方法
其实和初始化注释的方式相同,但是必须要注明「返回值」,不管是否返回。
def recommend(self, user):
"""
recommend one user
:param user: user's ID
:return:
"""
rank = dict()
interacted_items = self.train[user]
for i, pi in interacted_items.items():
for j, wj in sorted(self.W[i].items(), key=lambda x: x[1], reverse=True)[:10]:
...
rank = sorted(rank.items(), key=lambda x: x[1], reverse=True)
return [r[0] for r in rank]
部分注释
如果一个函数过长,你可以将每一部分的作用也可以注明,某些变量也可以添加注释,这里就按照每个人的编程习惯,例如:
def UserSimilarity(train):
"""
calculate interest similarity between users
:param train: train dataset
:return: user's similarity matrix
"""
# build inverse table for item_users
item_users = dict()
...
# calculate finial similarity matrix W
for u, related_users in W.items():
for v, cuv in related_users.items():
W[u][v] = cuv / np.sqrt(N[u] * N[v])
return W
总结
上述是潜心的一些编写代码的经验,如果有什么不对的地方,同学们可以私信我。如果喜欢的话,请给个关注哦!另外潜心也有个 「Python学习交流群」(没人),想要加入的也可以联系我。

往期精彩回顾
「通过Docs学Python」(三)内置类型:文本、集合以及映射
扫码关注更多精彩



我就知道你“在看”

本文详细介绍Python编程中的代码规范,涵盖代码格式、命名习惯、注释风格等,旨在提升代码质量和可读性。
浅谈Python代码规范&spm=1001.2101.3001.5002&articleId=106066797&d=1&t=3&u=2dcb00d0d4a24a0c9450c53ead6a4938)
146

被折叠的 条评论
为什么被折叠?



