Python样式指南

总览

· Python样式指南将使您能够编写简洁漂亮的Python代码

· 在本样式指南中了解不同的Python约定和Python编程的其他细微差别

介绍

您是否遇到过写得很差的Python代码?我说的是一个混乱的混乱局面,您不得不花几个小时才试图了解代码的去向。我知道你们很多人都会对此表示赞同。

编写代码是数据科学家或分析师角色的一部分。另一方面,编写漂亮而整洁的Python代码完全是另一回事。作为分析或数据科学领域(甚至软件开发)中精通的程序员,这很可能会使您的形象成败。

请记住–我们的Python代码只编写了一次,但是却被数十亿次阅读,可能是由不习惯我们的编程风格的查看者编写的。这在数据科学中显得尤为重要。那么我们如何编写这个所谓的漂亮的Python代码呢?

数据科学和分析领域的许多人都来自非编程背景。我们首先学习编程的基础知识,然后继续理解机器学习背后的理论,然后深入研究数据集。在此过程中,我们通常不练习硬核编程或注意编程约定。 

Python样式指南内容

· 为什么此Python样式指南对数据科学很重要?

· 什么是PEP8?

· 了解Python命名约定

· Python样式指南的代码布局

· 熟悉使用注释

· Python代码中的空格

· Python通用编程建议

· 自动格式化您的Python代码

为什么此Python样式指南对数据科学很重要?

有多种原因使格式化成为编程的重要方面,尤其是对于数据科学项目而言:

· 可读性

良好的代码格式将不可避免地提高代码的可读性。这不仅可以使您的代码更有条理,而且使读者更容易理解程序中发生的事情。如果您的程序运行成千上万行,这将特别有用。如果没有遵循正确的格式设置准则,那么拥有如此众多的数据框,列表,函数,图表等,您甚至很容易就无法跟踪自己的代码!

· 合作

如果您正在与大多数数据科学家合作的团队项目中进行协作,那么良好的格式设置将成为一项必不可少的任务。这样可以确保正确理解代码,而不会带来任何麻烦。同样,遵循通用的格式设置模式可以在整个项目生命周期中保持程序的一致性。

· Bug修复

当您需要修复程序中的错误时,拥有格式正确的代码也将为您提供帮助。缩进错误,命名不正确等容易使调试成为噩梦!因此,最好在正确的位置启动程序!

考虑到这一点,让我们快速浏览一下本文将介绍的PEP-8样式指南!

什么是PEP-8?

PEP-8(或Python增强建议)是Python编程的样式指南。它是由Guido van Rossum,Barry Warsaw和Nick Coghlan撰写的。它描述了编写漂亮易读的Python代码的规则。

遵循PEP-8编码风格将确保您的Python代码具有一致性,从而使其他读者,贡献者或您自己更容易理解它。

本文涵盖了PEP-8指南的最重要方面,例如如何命名Python对象,如何构建代码,何时包括注释和空格,以及最后一些通用的编程建议,这些建议很重要但大多数Python却容易忽略程序员。 

了解Python命名约定

莎士比亚有句著名的话:“名字叫什么?”。如果他那时遇到过程序员,他将得到一个迅速的答复-“很多!”。

是的,当您编写一段代码时,为变量,函数等选择的名称对代码的可理解性有很大影响。看看下面的代码:

#功能1

def func(x):

   一个= x.split()[0]

   b = x.split()[1]

   返回a,b

print(func('Analytics Vidhya'))

#功能2

def name_split(全名):

   first_name = full_name.split()[0]

   last_name = full_name.split()[1]

   返回名字,姓氏

打印(name_split('Analytics Vidhya'))

#输出

(“ Analytics”,“ Vidhya”)

(“ Analytics”,“ Vidhya”)

两种功能都可以完成相同的工作,但是即使没有任何评论,后一种功能也可以更好地了解引擎盖下正在发生的事情!这就是为什么在编写程序时选择正确的名称并遵循正确的命名约定会带来巨大不同的原因。话虽如此,让我们看一下如何在Python中命名对象!

开始的一般提示

这些技巧可用于命名任何实体,并应严格遵守。

· 尝试遵循相同的模式 -一致性是关键!

thisVariable,ThatVariable,some_other_variable,BIG_NO

· 避免使用长名,而又不要太过节俭

this_could_be_a_bad_name =“避免这个!”

t =“这也不好”

· 使用明智的描述性名称。这将在以后尝试记住代码的目的时提供帮助

X =“我的名字”#避免这种情况

full_name =“我的名字”#更好

· 避免使用以数字开头的名称

1_name =“真不好!”

· 避免在名称中使用@,!,#,$等特殊字符

phone_#昵称

命名变量

· 变量名应始终小写

博客=“ Analytics Vidhya”

· 对于更长的变量名,请在下划线中包括下划线。这提高了可读性

awesome_blog =“ Analytics Vidhya”

· 尽量不要使用单字符变量名,例如“ I”(大写i字母),“ O”(大写o字母),“ l”(小写L字母)。它们可能与数字1和0难以区分。请看一下:

O = 0 + l + I + 1

· 对全局变量遵循相同的命名约定

命名功能

· 请使用小写的下划线命名约定

· 使用表达性名称

#避免

def con():

    ...

# 这个更好。

def connect():

    ...

· 如果函数参数名称与关键字冲突,请使用下划线而不是缩写。例如,将break变成break_而不是brk

#避免名称冲突。

def break_time(break_):

    打印(“您的休息时间是”,“ break _”,“ long”)

类名

· 请遵循CapWord(或camelCase或StudlyCaps)的命名约定。只需将每个单词都以大写字母开头,并且单词之间不要包含下划线

#遵循CapWord约定

类MySampleClass:

    通过

· 如果一个类包含具有相同属性名称的子类,请考虑在该类属性上添加双下划线

这将确保该属性__ 年龄在类作为访问_Person__age。这是Python的名称处理,可确保没有名称冲突

班级人员:

    def __init __():

        年龄= 18

obj = Person()

obj .__ age#错误

obj._Person__age#正确

· 将后缀“ Error”用于异常类

类CustomError(Exception):

    “”“自定义例外类别”“”

命名类方法

· 实例方法(不附加任何字符串的基本类方法)的第一个参数应始终为self 这指向调用对象

· 类方法的第一个参数应始终为cls 这指向类,而不是对象实例

类SampleClass:

    def instance_method(self,del_):

        打印(“实例方法”)

    @classmethod

    def class_method(cls):

        打印(“类方法”)

软件包和模块名称

· 尽量使名称简短

· 应遵循小写命名约定

· 对于长模块名称,最好使用下划线

· 避免在软件包名称下划线

testpackage#软件包名称

sample_module.py#模块名称

常数名称

· 通常在模块内声明和分配常量

· 常量的命名约定是一种畸变。常数名称应全为大写字母

· 使用下划线表示更长的名称

#在global.py模块中跟随常量变量

PI = 3.14

重力= 9.8

SPEED_OF_Light = 3 * 10 ** 8

Python样式指南的代码布局

既然您知道了如何在Python中命名实体,那么您应该想到的下一个问题就是如何在Python中构建代码!老实说,这非常重要,因为如果没有适当的结构,您的代码可能会陷入困境,并且可能成为任何审阅者的最大选择。

因此,事不宜迟,让我们开始了解Python中的代码布局基础!

缩进

它是代码布局中最重要的一个方面,在Python中起着至关重要的作用。缩进指示要在块中包括哪些代码行来执行。缺少缩进可能是一个严重的错误。

缩进确定代码语句属于哪个代码块。想象一下试图编写一个嵌套的for循环代码。在相应的循环之外编写一行代码可能不会给您带来语法错误,但您肯定会遇到逻辑错误,这在调试方面可能会非常耗时。

请遵循以下有关缩进的要点,以确保Python脚本具有一致的结构。

· 始终遵循4空格缩进规则

#示例

如果值<0:

    打印(“负值”)

# 另一个例子

对于我在范围(5)中:

    打印(“严格遵守此规则!”)

· 优先在标签上使用空格

建议在选项卡上使用空格。但是,如果代码已经使用Tab缩进,则可以使用Tab。

如果是真的:

    print('使用4个缩进空格!')

· 将大型表达式分成几行

有几种处理这种情况的方法。一种方法是将后续语句与开头定界符对齐。

#与分隔符对齐。

def name_split(first_name,

               中间名字,

               姓)

# 另一个例子。

ans = solution(value_one,value_two,

               value_three,value_four)

第二种方法是利用4空格缩进规则。这将需要额外的缩进级别,以将参数与块内其余代码区分开来。

#利用额外的缩进。

def name_split(

        名字,

        中间名字,

        姓):

    打印(名字,中间名,姓氏)

最后,您甚至可以使用“悬挂缩进”。在Python的上下文中,悬挂缩进是指文本样式,其中包含括号的行以开括号结尾。缩进后续行,直到右括号为止。

#悬挂缩进。

ans =解决方案(

    value_one,value_two,

    value_three,value_four)

· 缩进我F-语句可能是一个问题

具有多个条件的if语句自然包含4个空格-if,空格和左括号。如您所见,这可能是一个问题。随后的行也将缩进,并且无法将if语句与它执行的代码块区分开。现在,我们该怎么办?

好吧,我们有几种方法可以解决它:

# 这是个问题。

如果(condition_one和

    condition_two):

    打印(“实施此”)

一种方法是使用额外的缩进级别!

#使用额外的缩进。

如果(condition_one和

        condition_two):

    打印(“实施此”)

另一种方法是在if语句条件和代码块之间添加注释,以区分两者:

# 添加评论。

如果(condition_one和

    condition_two):

    #此条件有效

    打印(“实施此”)

· 支架需要关闭

假设您有一个很长的值字典。您将所有键值对放在单独的行中,但是在右括号放在哪里?最后一行吗?接下来的线吗?如果是这样,您只是将其放在缩进的开头还是之后?

也有几种方法可以解决此问题。

一种方法是将右括号与上一行的第一个非空白字符对齐。

learning_path = {

    “步骤1”:“学习编程”,

    “步骤2”:“学习机器学习”,

    “第3步”:“骇客马拉松”

    }

第二种方法是将其作为新行的第一个字符。

learning_path = {

    “步骤1”:“学习编程”,

    “步骤2”:“学习机器学习”,

    “第3步”:“骇客马拉松”

}

· 二进制运算符之前的换行

如果您试图将太多的运算符和操作数放在一行中,那么它一定很麻烦。而是将其分成几行以提高可读性。

现在显而易见的问题–在运算符之前还是之后中断?惯例是在操作员之前打破。这有助于轻松确定操作符及其作用的操作数。

#在运算符之前换行。

gdp =(消耗量

      +政府支出

      +投资

      + net_exports

      )

使用空行

捆绑代码行只会使读者更难理解您的代码。使代码看起来更整洁和令人愉悦的一种好方法是在代码中引入相应数量的空行。

· 顶级函数和类应由两个空行分隔

#分离类和顶层函数。

类SampleClass():

    通过

def sample_function():

    打印(“顶级功能”)

· 类内的方法应用单个空白行分隔

#在类中分离方法。

类MyClass():

    def method_one():

        打印(“第一种方法”)

    def method_two(self):

        打印(“第二种方法”)

· 尽量不要在具有相关逻辑和功能的代码段之间包含空行

def remove_stopwords(文字):

    stop_words = stopwords.words(“英语”)

    令牌= word_tokenize(文本)

    clean_text = [如果单词不在stop_words中,则单词在单词中以单词为单位]

    返回clean_text

· 在函数中可以少用空白行来分隔逻辑部分。这使得更容易理解代码

def remove_stopwords(文字):

    stop_words = stopwords.words(“英语”)

    令牌= word_tokenize(文本)

    clean_text = [如果单词不在stop_words中,则单词在单词中以单词为单位]

    clean_text =''.join(clean_text)

    clean_text = clean_text.lower()

    返回clean_text

最大线长

· 一行中不超过79个字符

用Python编写代码时,不能将多于79个字符的字符压缩成一行。这是限制,应该成为使语句简短的指导原则。

· 您可以将语句分成多行,然后将其变成较短的代码行

#分成多行。

num_list = [y代表y,范围为(100)

            如果y%2 == 0

            如果y%5 == 0]

打印(num_list)

进口货

许多数据科学家喜欢使用Python的部分原因是因为大量的库使处理数据变得更加容易。因此,假设您最终将导入一堆库和模块以完成数据科学中的任何任务。

· 应该总是放在Python脚本的顶部

· 单独的库应在单独的行上导入

将numpy导入为np

将熊猫作为pd导入

df = pd.read_csv(r'/ sample.csv')

· 导入应按以下顺序分组:

o 标准库导入

o 相关第三方进口

o 本地应用程序/特定于库的导入

· 在每组进口之后都包含一个空白行

将numpy导入为np

将熊猫作为pd导入

导入matplotlib

从glob导入glob

导入空间

导入我的包裹

· 可以在同一行中从同一模块导入多个类

从数学导入单元开始

熟悉正确的Python注释

理解一段未注释的代码可能是一项艰巨的任务。即使对于原始代码编写者,也很难记住一段时间后代码行中到底发生了什么。

因此,最好在那时和那里评论您的代码,以便读者可以正确理解您尝试使用该特定代码段实现的目标。

包含评论的一般提示

· 一律以大写字母开头

· 评论应为完整句子

· 在更新代码时更新注释

· 避免发表明显的评论

阻止评论

· 描述跟随它们的一段代码

· 与代码段具有相同的缩进

· 以#和单个空格开头

#从用户输入的字符串中删除非字母数字字符。

汇入

raw_text = input('输入字符串:')

文字= re.sub(r'\ W +','',raw_text)

内联评论

· 这些注释与代码语句在同一行

· 应与代码语句至少分隔两个空格

· 以通常的#开头,后跟空格

· 不要用它们来陈述明显的

· 尽量少用它们,因为它们会分散注意力

info_dict = {}#用于存储提取的信息的字典

文档字符串

· 用于描述公共模块,类,函数和方法

· 也称为“文档字符串”

· 是什么让它们在其余评论中脱颖而出,是因为它们被包含在三引号“””之内

· 如果文档字符串以一行结尾,则在同一行末尾加上“”

· 如果文档字符串遇到多行,请将结尾的“””放在新行上

def square_num(x):

    “”“返回数字的平方。”“”

    返回x ** 2

def power(x,y):

    “”“多行注释。

       返回x升为y。

    “”

    返回x ** y

Python代码中的空格

编写漂亮的代码时,空白通常被忽略为琐碎的方面。但是正确使用空格可以极大地提高代码的可读性。它们有助于防止代码语句和表达式过于拥挤。这不可避免地帮助读者轻松地阅读了代码。

关键点

· 避免将空格立即放在方括号内

#正确的方法

df ['clean_text'] = df ['text']。apply(预处理)

· 切勿在逗号,分号或冒号前加上空格

#正确

name_split = lambda x:x.split()

#正确

· 字符和左括号之间不要包含空格

#正确

print('这是正确的方法')

#正确

对于我在范围(5)中:

    name_dict [i] = input_list [i]

· 使用多个运算符时,仅在优先级最低的运算符周围包含空格

#正确

ans = x ** 2 + b * x + c

· 在分片中,冒号充当二进制运算符

应将它们视为最低优先级的运算符。每个冒号周围必须包含等号

#正确

df_valid = df_train [lower_bound + 5:upper_bound-5]

· 应避免尾随空格

· 指示函数参数时,请勿在空格周围包含=符号

def exp(base,power = 2):

    返回基础**功率

· 始终将以下二进制运算符两边用单个空格括起来:

o 赋值运算符(=,+ =,-=等)

o 比较(==,<,>,!=,<>,<=,> =,in,not in,is,is not)

o 布尔值(与非)

#正确

布鲁克林= ['Amy','Terry','Gina','Jake']

计数= 0

在布鲁克林的名字:

    如果名称=='杰克':

        打印('酷')

        计数+ = 1

Python通用编程建议

通常,有多种方法可以编写一段代码。尽管他们完成了相同的任务,但最好还是使用推荐的方式编写更简洁的代码并保持一致性。在本节中,我已经介绍了其中一些。

· 为了与None之类的单例进行比较,请始终使用isis。不要使用相等运算符

#错误

如果名称!=无:

    打印(“不为空”)

#正确

如果名称不是None:

    打印(“不为空”)

· 不要使用比较运算符将布尔值比较为TRUE或FALSE。尽管使用比较运算符可能很直观,但是没有必要使用它。只需编写布尔表达式

#正确

如果有效:

    打印(“正确”)

#错误

如果有效==真:

    打印(“错误”)

· 不要将lambda函数绑定到标识符,而应使用通用函数。因为将lambda函数分配给标识符会破坏其目的。而且回溯会更容易

#喜欢这个

def func(x):

    不返回

#以上

func = lambda x:x ** 2

· 捕获异常时,请命名您正在捕获的异常。不要只使用裸机。当您试图中断执行时,这将确保异常块不会通过KeyboardInterrupt异常掩盖其他异常。

尝试:

    x = 1/0

除了ZeroDivisionError:

    print('不能被零除')

· 与您的退货声明一致。也就是说,函数中的所有return语句都应该返回表达式,或者都不返回。另外,如果return语句未返回任何值,则返回None而不是根本不返回任何值

#错误

定义样本(x):

    如果x> 0:

        返回x + 1

    elif x == 0:

        返回

    其他:

        返回x-1

#正确

定义样本(x):

    如果x> 0:

        返回x + 1

    elif x == 0:

        不返回

    其他:

        返回x-1

· 如果尝试检查字符串中的前缀或后缀,请使用“ .startswith()和” .endswith()代替字符串切片。这些更加清洁并且不易出错

#正确

如果name.endswith('and'):

    打印('很棒!')

自动格式化您的Python代码

使用小型程序时,格式化不会成为问题。但是,试想一下,对于成千上万行的复杂程序,必须遵循正确的格式化规则!这绝对是一项艰巨的任务。同样,在大多数情况下,您甚至都不会记住所有的格式化规则。那么,我们如何解决这个问题呢?好吧,我们可以使用一些自动格式化程序为我们完成这项工作!

自动格式化程序是一种程序,用于识别格式错误并将其修复到位。Black是一种这样的自动格式化程序,它通过自动将Python代码格式化为符合PEP8编码风格的代码来减轻您的负担。

您可以在终端中键入以下命令,使用pip轻松安装它:

点安装黑色

但是,让我们看看黑色在现实世界中实际上有多大帮助。让我们使用它来格式化以下类型较差的程序:

现在,我们要做的就是转到终端并输入以下命令:

黑色style_script.py

完成此操作后,如果要进行任何格式更改,黑色将已经就位,您将收到以下消息:

一旦您尝试再次打开它们,这些更改将反映在您的程序中:

如您所见,它已经正确格式化了代码,并且如果您错过任何格式化规则,肯定会对您有所帮助。

Black还可以与Atom,Sublime Text,Visual Studio Code甚至Jupyter笔记本之类的编辑器集成!这肯定是您扩展到您的编辑器的一项扩展。

尾注

在Python样式指南中,我们涵盖了很多关键点。如果您在整个代码中始终遵循这些原则,那么最终您将获得更清晰易读的代码。

同样,当您在一个项目团队中工作时,遵循一个通用的标准是有益的。它使其他合作者更容易理解。继续,并开始将这些样式提示纳入您的Python代码中!

发表评论

您的电子邮箱地址不会被公开。