做者|ANIRUDDHA BHANDARI
编译|VK
来源|Analytics Vidhyapython
你有没有遇到过一段写得很糟糕的Python代码?我知道大家不少人都会点头的。程序员
编写代码是数据科学家或分析师角色的一部分。另外一方面,编写漂亮整洁的Python代码彻底是另外一回事。做为一个精通分析或数据科学领域(甚至软件开发)的程序员,这极可能会改变你的形象。编程
那么,咱们如何编写这种所谓漂亮的Python代码呢?bash
欢迎学习Python风格教程app
数据科学和分析领域的许多人来自非编程背景。咱们先从学习编程的基础知识开始,接着理解机器学习背后的理论,而后开始征服数据集。机器学习
在这个过程当中,咱们常常不练习核心编程,也不注意编程惯例。ide
这就是本Python风格教程将要解决的问题。咱们将回顾PEP-8文档中描述的Python编程约定,你将成为一个更好的程序员!函数
有几个缘由使格式化成为编程的一个重要方面,尤为是对于数据科学项目:布局
好的代码格式将不可避免地提升代码的可读性。这不只会使你的代码更有条理,并且会使读者更容易理解程序中正在发生的事情。若是你的程序运行了数千行,这将特别有用。学习
你会有不少的数据帧、列表、函数、绘图等,若是不遵循正确的格式准则,你甚至会很容易失去对本身代码的跟踪!
若是你在一个团队项目上合做,大多数数据科学家都会这样作,那么好的格式化就成了一项必不可少的任务。
这样能够确保代码被正确理解而不产生任何麻烦。此外,遵循一个通用的格式模式能够在整个项目生命周期中保持程序的一致性。
当你须要修复程序中的错误时,拥有一个格式良好的代码也将有助于你。错误的缩进、不恰当的命名等都很容易使调试成为一场噩梦!
所以,最好是以正确的编写风格来开始编写你的程序!
考虑到这一点,让咱们快速概述一下本文将介绍的PEP-8样式教程!
PEP-8或Python加强建议是Python编程的风格教程。它是由吉多·范罗森、巴里·华沙和尼克·科格兰写的。它描述了编写漂亮且可读的Python代码的规则。
遵循PEP-8的编码风格将确保Python代码的一致性,从而使其余读者、贡献者或你本身更容易理解代码。
本文介绍了PEP-8指导原则中最重要的方面,如如何命名Python对象、如何构造代码、什么时候包含注释和空格,最后是一些很重要但很容易被大多数Python程序员忽略的通常编程建议。
让咱们学习编写更好的代码!
官方PEP-8文档能够在这里找到。
https://www.python.org/dev/pe...
莎士比亚有句名言:“名字里有什么?”. 若是他当时遇到了一个程序员,他会很快获得一个答复——“不少!”.
是的,当你编写一段代码时,你为变量、函数等选择的名称对代码的可理解性有很大的影响。看看下面的代码:
# 函数 1 def func(x): a = x.split()[0] b = x.split()[1] return a, b print(func('Analytics Vidhya')) # 函数 2 def name_split(full_name): first_name = full_name.split()[0] last_name = full_name.split()[1] return first_name, last_name print(name_split('Analytics Vidhya'))
# 输出 ('Analytics', 'Vidhya') ('Analytics', 'Vidhya')
这两个函数的做用是同样的,可是后者提供了一个更好的直觉让咱们知道发生了什么,即便没有任何注释!
这就是为何选择正确的名称和遵循正确的命名约定能够在编写程序时能够产生巨大的不一样。话虽如此,让咱们看看如何在Python中命名对象!
这些技巧能够应用于命名任何实体,而且应该严格遵照。
thisVariable, ThatVariable, some_other_variable, BIG_NO
this_could_be_a_bad_name = “Avoid this!” t = “This isn\’t good either”
X = “My Name” # 防止这个 full_name = “My Name” # 这个更好
1_name = “This is bad!”
phone_ # 很差
blog = "Analytics Vidhya"
awesome_blog = "Analytics Vidhya"
O = 0 + l + I + 1
# 避免 def con(): ... # 这个更好 def connect(): ...
# 避免名称冲突 def break_time(break_): print(“Your break time is”, break_,”long”)
# 遵循CapWord class MySampleClass: pass
这将确保类Person中的属性__age被访问为 _Person__age。这是Python的名称混乱,它确保没有名称冲突
class Person: def __init__(self): self.__age = 18 obj = Person() obj.__age # 错误 obj._Person__age # 正确
class CustomError(Exception): “””自定义异常类“””
class SampleClass: def instance_method(self, del_): print(“Instance method”) @classmethod def class_method(cls): print(“Class method”)
testpackage # 包名称 sample_module.py # 模块名称
# 下列常量变量在global.py模块 PI = 3.14 GRAVITY = 9.8 SPEED_OF_Light = 3*10**8
如今你已经知道了如何在Python中命名实体,下一个问题应该是如何用Python构造代码!
老实说,这是很是重要的,由于若是没有适当的结构,你的代码可能会出问题,对任何评审人员来讲都是最大的障碍。
因此,不用再多费吹灰之力,让咱们来了解一下Python中代码布局的基础知识吧!
它是代码布局中最重要的一个方面,在Python中起着相当重要的做用。缩进告诉代码块中要包含哪些代码行以供执行。缺乏缩进多是一个严重的错误。
缩进肯定代码语句属于哪一个代码块。想象一下,尝试编写一个嵌套的for循环代码。在各自的循环以外编写一行代码可能不会给你带来语法错误,但你最终确定会遇到一个逻辑错误,这可能会在调试方面耗费时间。
遵循下面提到的缩进风格,以得到一致的Python脚本风格。
# 示例 if value<0: print(“negative value”) # 另外一个例子 for i in range(5): print(“Follow this rule religiously!”)
建议用空格代替制表符。可是当代码已经用制表符缩进时,可使用制表符。
if True: print('4 spaces of indentation used!')
处理这种状况有几种方法。一种方法是将后续语句与起始分隔符对齐。
# 与起始分隔符对齐。 def name_split(first_name, middle_name, last_name) # 另外一个例子。 ans = solution(value_one, value_two, value_three, value_four)
第二种方法是使用4个空格的缩进规则。这将须要额外的缩进级别来区分参数和块内其余代码。
# 利用额外的缩进。 def name_split( first_name, middle_name, last_name): print(first_name, middle_name, last_name)
最后,你甚至可使用“悬挂缩进”。悬挂缩进在Python上下文中是指包含圆括号的行以开括号结束的文本样式,后面的行缩进,直到括号结束。
# 悬挂缩进 ans = solution( value_one, value_two, value_three, value_four)
带有多个条件的if语句天然包含4个空格。如你所见,这多是个问题。随后的行也将缩进,而且没法区分if语句和它执行的代码块。如今,咱们该怎么办?
好吧,咱们有几种方法能够绕过它:
# 这是个问题。 if (condition_one and condition_two): print(“Implement this”)
一种方法是使用额外的缩进!
# 使用额外的缩进 if (condition_one and condition_two): print(“Implement this”)
另外一种方法是在if语句条件和代码块之间添加注释,以区分这二者:
# 添加注释。 if (condition_one and condition_two): # 此条件有效 print(“Implement this”)
假设你有一个很长的字典。你将全部的键值对放在单独的行中,可是你将右括号放在哪里?是在最后一行吗?仍是跟在最后一个键值对?若是放在最后一行,右括号位置的缩进是多少?
也有几种方法能够解决这个问题。
一种方法是将右括号与前一行的第一个非空格字符对齐。
# learning_path = { ‘Step 1’ : ’Learn programming’, ‘Step 2’ : ‘Learn machine learning’, ‘Step 3’ : ‘Crack on the hackathons’ }
第二种方法是把它做为新行的第一个字符。
learning_path = { ‘Step 1’ : ’Learn programming’, ‘Step 2’ : ‘Learn machine learning’, ‘Step 3’ : ‘Crack on the hackathons’ }
若是你试图在一行中放入太多的运算符和操做数,这确定会很麻烦。相反,为了更好的可读性,把它分红几行。
如今很明显的问题是——在操做符以前仍是以后中断?惯例是在操做符以前断行。这有助于识别操做符和它所做用的操做数。
# 在操做符以前断行 gdp = (consumption + government_spending + investment + net_exports )
将代码行聚在一块儿只会使读者更难理解你的代码。使代码看起来更整洁、更美观的一个好方法是在代码中引入相应数量的空行。
#分离类和顶层函数 class SampleClass(): pass def sample_function(): print("Top level function")
# 在类中分离方法 class MyClass(): def method_one(self): print("First method") def method_two(self): print("Second method")
def remove_stopwords(text): stop_words = stopwords.words("english") tokens = word_tokenize(text) clean_text = [word for word in tokens if word not in stop_words] return clean_text
def remove_stopwords(text): stop_words = stopwords.words("english") tokens = word_tokenize(text) clean_text = [word for word in tokens if word not in stop_words] clean_text = ' '.join(clean_text) clean_text = clean_text.lower() return clean_text
当你用Python编写代码时,不能在一行中压缩超过79个字符。这是限制,应该是保持声明简短的指导原则。
# 分红多行 num_list = [y for y in range(100) if y % 2 == 0 if y % 5 == 0] print(num_list)
许多数据科学家之因此喜欢使用Python,部分缘由是由于有太多的库使得处理数据更加容易。所以,咱们假设你最终将导入一堆库和模块来完成数据科学中的任何任务。
import numpy as np import pandas as pd df = pd.read_csv(r'/sample.csv')
导入应按如下顺序分组:
import numpy as np import pandas as pd import matplotlib from glob import glob import spaCy import mypackage
from math import ceil, floor
理解一段未注释的代码多是一项费力的工做。即便是代码的原始编写者,也很难记住一段时间后代码行中到底发生了什么。
所以,最好及时对代码进行注释,这样读者就能够正确地理解你试图用这段代码实现什么。
# 从用户输入字符串中删除非字母数字字符。 import re raw_text = input(‘Enter string:‘) text = re.sub(r'\W+', ' ', raw_text)
info_dict = {} # 字典,用于存储提取的信息
def square_num(x): """返回一个数的平方.""" return x**2 def power(x, y): """多行注释。 返回x**y. """ return x**y
在编写漂亮的代码时,空格经常被忽略为一个微不足道的方面。可是正确使用空格能够大大提升代码的可读性。它们有助于防止代码语句和表达式过于拥挤。这不可避免地帮助读者轻松地浏览代码。
# 正确的方法 df[‘clean_text’] = df[‘text’].apply(preprocess)
# 正确 name_split = lambda x: x.split()
# 正确 print(‘This is the right way’) # 正确 for i in range(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): return base**power
请始终在如下二进制运算符的两边用单个空格括起来:
# 正确 brooklyn = [‘Amy’, ‘Terry’, ‘Gina’, 'Jake'] count = 0 for name in brooklyn: if name == ‘Jake’: print(‘Cool’) count += 1
一般,有不少方法来编写一段代码。当它们完成相同的任务时,最好使用推荐的编写方法并保持一致性。我在这一节已经介绍了其中的一些。
# 错误 if name != None: print("Not null") # 正确 if name is not None: print("Not null")
# 正确 if valid: print("Correct") # 错误 if valid == True: print("Wrong")
# 选择这个 def func(x): return None # 而不是这个 func = lambda x: x**2
try: x = 1/0 except ZeroDivisionError: print('Cannot divide by zero')
# 错误 def sample(x): if x > 0: return x+1 elif x == 0: return else: return x-1 # 正确 def sample(x): if x > 0: return x+1 elif x == 0: return None else: return x-1
若是要检查字符串中的前缀或后缀,请使用“.startswith()”和“.endswith()",而不是字符串切片。它们更干净,更不容易出错
# 正确 if name.endswith('and'): print('Great!')
当你编写小的程序时,格式化不会成为一个问题。可是想象一下,对于一个运行成千行的复杂程序,必须遵循正确的格式规则!这绝对是一项艰巨的任务。并且,大多数时候,你甚至不记得全部的格式规则。
咱们如何解决这个问题呢?好吧,咱们能够用一些自动格式化程序来完成这项工做!
自动格式化程序是一个程序,它能够识别格式错误并将其修复到位。Black就是这样一种自动格式化程序,它能够自动将Python代码格式化为符合PEP8编码风格的代码,从而减轻你的负担。
BLACK:https://pypi.org/project/black/
经过在终端中键入如下命令,可使用pip轻松安装它:
pip install black
可是让咱们看看black在现实世界中有多大的帮助。让咱们用它来格式化如下类型错误的程序:
如今,咱们要作的就是,前往终端并键入如下命令:
black style_script.py
完成后,black可能已经完成了更改,你将收到如下消息:
一旦再次尝试打开程序,这些更改将反映在程序中:
正如你所看到的,它已经正确地格式化了代码,在你不当心违反格式化规则的状况下它会有帮助。
Black还能够与Atom、Sublime Text、visualstudio代码,甚至Jupyter Notebook集成在一块儿!这无疑是一个你永远不会错过的插件。
除了black,还有其余的自动格式化程序,如autoep8和yapf,你也能够尝试一下!
咱们已经在Python风格教程中讨论了不少关键点。若是你在代码中始终遵循这些原则,那么你将最终获得一个更干净和可读的代码。
另外,当你做为一个团队在一个项目中工做时,遵循一个共同的标准是有益的。它使其余合做者更容易理解。开始在Python代码中加入这些风格技巧吧!
原文连接:https://www.analyticsvidhya.c...
欢迎关注磐创AI博客站:
http://panchuang.net/
sklearn机器学习中文官方文档:
http://sklearn123.com/
欢迎关注磐创博客资源汇总站:
http://docs.panchuang.net/