乐趣区

关于人工智能:如何编写简洁美观的Python代码

作者 |ANIRUDDHA BHANDARI
编译 |VK
起源 |Analytics Vidhya

概述

  • Python 格调教程将使你可能编写整洁丑陋的 Python 代码
  • 在这个格调教程中学习不同的 Python 约定和 Python 编程的其余细微差别

介绍

你有没有遇到过一段写得很蹩脚的 Python 代码?我晓得你们很多人都会拍板的。

编写代码是数据科学家或分析师角色的一部分。另一方面,编写丑陋整洁的 Python 代码齐全是另一回事。作为一个精通剖析或数据迷信畛域(甚至软件开发)的程序员,这很可能会扭转你的形象。

那么,咱们如何编写这种所谓丑陋的 Python 代码呢?

欢送学习 Python 格调教程

数据迷信和剖析畛域的许多人来自非编程背景。咱们先从学习编程的基础知识开始,接着了解机器学习背地的实践,而后开始驯服数据集。

在这个过程中,咱们常常不练习外围编程,也不留神编程常规。

这就是本 Python 格调教程将要解决的问题。咱们将回顾 PEP- 8 文档中形容的 Python 编程约定,你将成为一个更好的程序员!

目录

  • 为什么这个 Python 格调的教程对数据迷信很重要?
  • 什么是 PEP8?
  • 理解 Python 命名约定
  • Python 格调教程的代码布局
  • 相熟正确的 Python 正文
  • Python 代码中的空格
  • Python 的个别编程倡议
  • 主动格式化 Python 代码

为什么这个 Python 格调的教程对数据迷信很重要

有几个起因使格式化成为编程的一个重要方面,尤其是对于数据迷信我的项目:

  • 可读性

好的代码格局将不可避免地进步代码的可读性。这不仅会使你的代码更有条理,而且会使读者更容易了解程序中正在产生的事件。如果你的程序运行了数千行,这将特地有用。

你会有很多的数据帧、列表、函数、绘图等,如果不遵循正确的格局准则,你甚至会很容易失去对本人代码的跟踪!

  • 合作

如果你在一个团队我的项目上单干,大多数数据科学家都会这样做,那么好的格式化就成了一项必不可少的工作。

这样能够确保代码被正确理解而不产生任何麻烦。此外,遵循一个通用的格局模式能够在整个我的项目生命周期中放弃程序的一致性。

  • Bug 修复

当你须要修复程序中的谬误时,领有一个格局良好的代码也将有助于你。谬误的缩进、不失当的命名等都很容易使调试成为一场噩梦!

因而,最好是以正确的编写格调来开始编写你的程序!

思考到这一点,让咱们疾速概述一下本文将介绍的 PEP- 8 款式教程!

什么是 PEP-8

PEP- 8 或 Python 加强倡议是 Python 编程的格调教程。它是由吉多·范罗森、巴里·华沙和尼克·科格兰写的。它形容了编写丑陋且可读的 Python 代码的规定。

遵循 PEP- 8 的编码格调将确保 Python 代码的一致性,从而使其余读者、贡献者或你本人更容易了解代码。

本文介绍了 PEP- 8 领导准则中最重要的方面,如如何命名 Python 对象、如何结构代码、何时蕴含正文和空格,最初是一些很重要但很容易被大多数 Python 程序员疏忽的个别编程倡议。

让咱们学习编写更好的代码!

官网 PEP- 8 文档能够在这里找到。

https://www.python.org/dev/pe…

理解 Python 命名约定

莎士比亚有句名言:“名字里有什么?”. 如果他过后遇到了一个程序员,他会很快失去一个回答——“很多!”.

是的,当你编写一段代码时,你为变量、函数等抉择的名称对代码的可了解性有很大的影响。看看上面的代码:

# 函数 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"
  • 尽量不要应用单字符变量名,如“I”(大写 I 字母)、“O”(大写 O 字母)、“l”(小写字母 l)。它们与数字 1 和 0 无奈辨别。看看:
O = 0 + l + I + 1
  • 全局变量的命名遵循雷同的约定

函数命名

  • 遵循小写和下划线命名约定
  • 应用富裕表现力的名字
# 防止
def con():
    ...
# 这个更好
def connect():
    ...
  • 如果函数参数名与关键字抵触,请应用尾随下划线而不是缩写。例如,将 break 转换为 break_u 而不是 brk
# 防止名称抵触
def break_time(break_):
    print(“Your break time is”, break_,”long”)

类名命名

  • 遵循 CapWord(或 camelCase 或 StudlyCaps)命名约定。每个单词以大写字母结尾,单词之间不要加下划线
# 遵循 CapWord
class MySampleClass:
    pass
  • 如果类蕴含具备雷同属性名的子类,请思考向类属性增加双下划线

这将确保类 Person 中的属性__age 被拜访为 _Person__age。这是 Python 的名称凌乱,它确保没有名称抵触

class Person:
    def __init__(self):
        self.__age = 18

obj = Person() 
obj.__age  # 谬误
obj._Person__age  # 正确 
  • 对异样类应用后缀“Error”
class CustomError(Exception):“””自定义异样类“””

类办法命名

  • 实例办法(不附加字符串的根本类办法)的第一个参数应始终为 self。它指向调用对象
  • 类办法的第一个参数应始终为 cls。这指向类,而不是对象实例
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 中代码布局的基础知识吧!

缩进

它是代码布局中最重要的一个方面,在 Python 中起着至关重要的作用。缩进通知代码块中要蕴含哪些代码行以供执行。短少缩进可能是一个重大的谬误。

缩进确定代码语句属于哪个代码块。设想一下,尝试编写一个嵌套的 for 循环代码。在各自的循环之外编写一行代码可能不会给你带来语法错误,但你最终必定会遇到一个逻辑谬误,这可能会在调试方面消耗工夫。

遵循上面提到的缩进格调,以取得统一的 Python 脚本格调。

  • 始终遵循 4 空格缩进规定
# 示例
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 语句可能是一个问题

带有多个条件的 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

行最大长度

  • 一行不超过 79 个字符

当你用 Python 编写代码时,不能在一行中压缩超过 79 个字符。这是限度,应该是放弃申明简短的领导准则。

  • 你能够将语句拆分为多行,并将它们转换为较短的代码行
# 分成多行
num_list = [y for y in range(100) 
            if y % 2 == 0 
            if y % 5 == 0]
print(num_list)

导入包

许多数据科学家之所以喜爱应用 Python,局部起因是因为有太多的库使得解决数据更加容易。因而,咱们假如你最终将导入一堆库和模块来实现数据迷信中的任何工作。

  • 应该始终位于 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

相熟正确的 Python 正文

了解一段未正文的代码可能是一项费劲的工作。即便是代码的原始编写者,也很难记住一段时间后代码行中到底产生了什么。

因而,最好及时对代码进行正文,这样读者就能够正确地了解你试图用这段代码实现什么。

个别提醒

  • 正文总是以大写字母结尾
  • 正文应该是残缺的句子
  • 更新代码时更新正文
  • 防止写不言而喻之事的正文

正文的格调

  • 形容它们前面的代码段
  • 与代码段有雷同的缩进
  • 从一个空格开始
# 从用户输出字符串中删除非字母数字字符。import re

raw_text = input(‘Enter string:‘)
text = re.sub(r'\W+', ' ', raw_text)

内联正文

  • 这些正文与代码语句位于同一行
  • 应与代码语句至多分隔两个空格
  • 以通常的 #结尾,而后是空格
  • 不要用它们来陈说不言而喻的事件
  • 尽量少用它们,因为它们会扩散注意力
info_dict = {}  # 字典,用于存储提取的信息 

文档字符串

  • 用于形容公共模块、类、函数和办法
  • 也称为“docstrings”
  • 它们之所以能在其余正文中怀才不遇,是因为它们是用三重引号括起来的
  • 如果 docstring 以单行结尾,则在同一行中蕴含结束符“””
  • 如果 docstring 分为多行,请在新行中加上结束符“””
def square_num(x):
    """返回一个数的平方."""
    return x**2

def power(x, y):
    """ 多行正文。返回 x **y.
    """
    return x**y

Python 代码中的空格

在编写丑陋的代码时,空格经常被疏忽为一个微不足道的方面。然而正确应用空格能够大大提高代码的可读性。它们有助于避免代码语句和表达式过于拥挤。这不可避免地帮忙读者轻松地浏览代码。

要害

  • 防止将空格立刻放在括号内
# 正确的办法
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
  • 请始终在以下二进制运算符的两边用单个空格括起来:

    • 赋值运算符(=,+=,-=,等)
    • 比拟(=,<,>!=,<>,<=,>=,输出,不在,是,不是)
    • 布尔值(and,or,not)
# 正确
brooklyn = [‘Amy’,‘Terry’,‘Gina’, 'Jake']
count = 0
for name in brooklyn:
    if name ==‘Jake’:
        print(‘Cool’)
        count += 1

Python 的个别编程倡议

通常,有很多办法来编写一段代码。当它们实现雷同的工作时,最好应用举荐的编写办法并放弃一致性。我在这一节曾经介绍了其中的一些。

  • 与“None”之类的进行比拟时,请始终应用“is”或“is not”。不要应用相等运算符
# 谬误
if name != None:
    print("Not null")
# 正确
if name is not None:
    print("Not null")
  • 不要应用比拟运算符将布尔值与 TRUE 或 FALSE 进行比拟。尽管应用比拟运算符可能很直观,但没有必要应用它。只需编写布尔表达式
# 正确
if valid:
    print("Correct")
# 谬误
if valid == True:
    print("Wrong")
  • 与其将 lambda 函数绑定到标识符,不如应用泛型函数。因为将 lambda 函数调配给标识符违反了它的目标。回溯也会更容易
# 抉择这个
def func(x):
    return None

# 而不是这个
func = lambda x: x**2
  • 捕捉异样时,请命名要捕捉的异样。不要只应用一个赤裸裸的例外。这将确保当你试图中断执行时,异样块不会通过键盘中断异样来覆盖其余异样
try:
    x = 1/0
except ZeroDivisionError:
    print('Cannot divide by zero')
  • 与你的返回语句保持一致。也就是说,一个函数中的所有返回语句都应该返回一个表达式,或者它们都不应该返回表达式。另外,如果 return 语句不返回任何值,则返回 None 而不是什么都不返回
# 谬误
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!')

主动格式化 Python 代码

当你编写小的程序时,格式化不会成为一个问题。然而设想一下,对于一个运行成千行的简单程序,必须遵循正确的格局规定!这相对是一项艰巨的工作。而且,大多数时候,你甚至不记得所有的格局规定。

咱们如何解决这个问题呢?好吧,咱们能够用一些主动格式化程序来实现这项工作!

主动格式化程序是一个程序,它能够辨认格局谬误并将其修复到位。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/

退出移动版