python样式

目录

Python 风格第一部分 - PEP8

文字是可读的

可读性 1 - 函数和变量名称

可读性 2 - PEP8 策略

缩进 4 个空格

项目之间只有一个空格

括号内无空格

逗号/冒号后的空格

切片异常

使用一致的引号

Def 前有 2 个空行

Def 中的空行

更喜欢!=和not in

不要写:if x == True

从代码中删除通行证

# 内联注释

与之比较==

例外is None​

为什么需要is None?

长线的历史

参数分解线

用括号分隔长行

命名参数异常

Python 关键字

“len” 规则:不要使用内置函数作为变量名

一个关于可读性的小笑话


Python 风格第一部分 - PEP8

CS106A 不仅仅教授编码。它一直教授如何以良好的风格编写干净的代码。您的部门负责人将与您讨论代码的正确性,并为您提供良好风格的指导。

杂乱的代码效果很差 — 难以阅读,难以调试。为了帮助您养成正确的习惯,我们希望您始终提交干净的代码,当然,我们所有的示例也应该具有良好的干净风格。

文字是可读的

良好风格的目标是“可读”的代码,这意味着当有人浏览代码时,代码的作用就会一览无余。

经验表明,可读性强的代码在构建和调试时耗费的时间更少。调试尤其会耗费大量时间,因此,学习编写干净的代码并保持代码干净是我们始终要做的事情。就像外科医生保持双手干净一样,这是正确的做法,我们会努力始终养成这种习惯。

可读性 1 - 函数和变量名称

实现良好可读性的第一步是良好的变量和函数名称,如以下示例所示:

...
url = 获取浏览器网址()
如果有安全问题(url):
    display_alert(‘该网址看上去不太可靠!’)
别的:
    html = 下载网址(网址)
    显示html(html)
...

代码的叙述步骤从良好的函数和变量名称(本质上是叙述中的动词和名词)中显而易见。这里不需要其他注释。仅凭名称就使其具有可读性。

函数是代码中的操作,因此我们更喜欢使用动词名称,例如“display_alert”或“remove_url”,以说明函数的作用。变量就像代码中的名词,因此我们更喜欢使用能够反映变量存储内容的名称,例如“urls”或“original_image”或“resized_image”。我们将在 Style 2 文档中更详细地讨论命名

可读性 2 - PEP8 策略

Python 是一个协作、免费和开源项目。“PEP”(Python 增强提案)是 Python 开发中使用的书面提案。

PEP8是最早的 PEP 之一,它是一套用于编写“标准”风格 Python 的统一样式和格式规则,因此您的代码对于阅读或修改它的任何人来说都具有正确的外观。这非常类似于英语拼写改革,其中“public”是标准拼写,而“publick”已不再使用,看起来很奇怪,有点令人讨厌。

以下是我们将使用的最重要的 PEP8 规则。您提交的代码应遵守 PEP8。

缩进 4 个空格

用 4 个空格缩进代码。def/if/for/while 行以冒号结尾,其包含的行从下一行开始,所有行都缩进 4 个空格,如下所示:

如果颜色=='红色':
    颜色='绿色'
    打印(颜色)

在早期的 Python 中,有些人使用 2 个空格或制表符。这些做法已经消失,现在 4 个空格才是标准。

项目之间只有一个空格

大多数代码行都混合了变量和“运算符”,例如+ * / = >=。使用一个空格将运算符和项与运算符彼此分隔:

边界 = x * 12 + 13
如果 x >= 4:
    打印 (x + 2)

括号内无空格

左右括号和方括号与其内容之间没有空格隔开。函数调用的左括号紧挨着函数名:

run_along(1,2 * 3,'hi') 
bark() 
lst = [1,2,z * 6]

逗号/冒号后的空格

逗号或冒号后面有 1 个空格,但前面没有空格。

foo(1, 'hello', 42) # 逗号:前有 0 个空格,后有 1 个空格
[1, 2, 3] # 例如列表
{'a': 1, 'b': 2} # 例如字典

切片异常

切片是上述规则的一个例外。切片中的冒号可以没有空格,最常见的写法是这样的:

s[start:end + 1] # 切片 - 无空格

PEP8 规则是宽容的,即切片冒号不应有空格,如上所示,或者两边各有 1 个空格,像+

使用一致的引号

Python 字符串可以写在单引号中,如'Hello'或双引号中,如 "there"。PEP8 要求程序选择一种引号样式并始终如一地使用它。对于 CS106A,我们建议只使用单引号。单引号稍微简单一些,因为它不需要 Shift 键。不用考虑使用哪个引号,这样可以释放宝贵的脑细胞来做其他事情。

Def 前有 2 个空行

PEP8 要求文件中的每个 def 前有 2 个空行。这是较弱的 PEP8 规则之一。如果您的代码在函数之间有 3 行,我们不会对您的代码感到不满。

Def 中的空行

如果代码行有自然阶段 — 几行设置文件,几行排序键 — 使用 def 中的空行将这些阶段彼此分开,就像将文章分成几段一样。标准要求“谨慎”使用空行。

更喜欢!=not in

这是两种均能正常工作的等效形式之间的一种选择。我们更喜欢不相等和不属于测试的“快捷”形式,如下所示:

如果不是 s == 'donut':# 否
    ...

如果 s != 'donut':# 是
    ...


如果食物中没有 'donut':# 否
    ...

如果食物中没有 'donut':# 是
    ...

这些形式按照更符合自然措辞的方式排列代码,例如“s 不是甜甜圈”或“甜甜圈不在食物中”。

不要写:if x == True

在 if/while 测试中,布尔 True/False 的求值方式比表面上看起来要复杂一些。简单的规则是:不要在 if/while 测试中 写if x == True或。if x == False

假设我们有一个print_greeting()接受shout_mode参数的函数。

不要这样写:

def print_greeting(words, scream_mode): 
    if scream_mode == True: # NO 不像这样
        print(words.upper()) 
    else 
        print(words)

结构本身if可以区分TrueFalse值。因此,编写代码以直接将布尔值赋予shout_modeif如下所示:

def print_greeting(words, scream_mode): 
    if scream_mode: # YES 像这样
        print(words.upper()) 
    else: 
        print(words)

要反转逻辑,请不要使用== Falsenot像这样使用:

def print_greeting(words, scream_mode): 
    if not scream_mode: 
        print('没有喊叫') 
    else: 
        print(words)

从代码中删除通行证

Python 中的指令pass是一个占位符行,实际上不执行任何操作。它很少用于常规生产代码。然而,在编码练习中,通常会有一些样板代码,其中标记了学生代码的位置。提交代码之前,请从代码中 pass删除所有标记。pass

# 内联注释

最好添加 #“内联”注释来解释特别不明显或有趣的代码的作用。当代码本身可以很好地显示该行的作用时,内联注释是不需要的。

1. 对于以下几行,代码很好地说明了一切,因此除了好的变量和函数名称之外,不需要内联注释。大多数代码行都是这样的。

count += 1 
total_len = len(名称) + len(地址)

特别是,避免添加重复代码本身内容的评论。

i += 1 # 将 i 加 1

2. 内联注释是合适的,如下例所示,解释一段不太明显的代码完成了什么——解决工作目标,而不是重新陈述所使用的运算符。

# 将 i 增加到下一个 10 的倍数
i = 10 * (i // 10 + 1)

内联注释提供了从行本身看不出来的有用信息。

3. 内联注释的另一个重要用途是指出代码未按显示执行的情况。这说明了可读性 - 代码未按其变量和函数名称所暗示的那样执行,因此内联注释可以帮助澄清问题。

vendor.add('AT&T') 
vendor.add('Stanford University') 
vendor.add('T-Mobile') 
# 注意:我们在这里传递“T-Mobile”,但由于历史
# 原因,支付系统重写并
在内部使用#“Vodafone”。

教学中使用的示例代码通常比常规生产代码具有更多的内联注释,因为在教学中我们很多时候想要指出或解释一行中显示的技术。

与之比较==

在 Python 中比较两个值的常用方法是什么?答案是:使用==如下运算符:

if word == 'meh': 
    print('热情低落')

它适用于字符串、整数、列表,几乎适用于所有东西。了解==运算符是最重要的。但是,下面有一个例外。

例外is None

比较运算符==是比较任意两个值的常用方法,我们不会标记出仅使用 的 CS106A 代码==

但是 PEP8 中有一条规则要求使用不同的比较形式,因此您最终应该学习它。此外,您可能会注意到您的 Python 编辑器会因为这条 PEP8 规则而 None抱怨比较。x == None

PEP8 要求与特殊值的比较NoneTrue并且False应该使用isis not比较而不是==,如下所示:

如果单词为 None:是,则“为 None”
    打印('此处无)

如果结果不为 None:是,则“不为 None”
    打印('得到结果')

如果单词 == None:否,则避免“== None”
    打印('Nada')

到目前为止,此规则最常见的应用是针对值None,因此您可以将其视为规则is None。此要求的原因有些晦涩难懂,但如果您好奇的话,下面会解释。如果代码意外地使用了==而不是,代码几乎肯定会完美运行。无法正确比较 的is情况非常非常罕见。 ==None

不幸的是,反之则不然。如果is在程序员想要使用 的地方编写了 代码==,那么它通常无法正常工作。因此,程序员应该关注==哪个是常见且可靠的。程序员不应该将is运算符视为经常使用的东西,除了这个关于 的强制性情况is None。我们不会标记使用 的学生代码,而是在课堂上提到它时 == None提及首选形式。is None

有关其操作的详细信息, 请参阅运算符部分。

为什么需要is None

您可能会认为is None使用这种形式是is因为与内存和副本有关,但其实是出于其他原因。之所以存在这种要求,是因为数据类型可以以这样的方式is None提供自定义定义,即在实际为假的情况下声称为真。这是一种不合理的定义,但这是可能的,而且有时确实发生过。标准 Python 安装中没有数据类型具有这种奇怪的行为,这就是为什么它通常可以正常工作。但是,项目中的代码可能有这种行为,因此针对这种情况,PEP8 要求使用这种形式。这避免了该问题,因为数据类型可以自定义,但运算符不能自定义。 ==x == None==== Noneis None==is

长线的历史

在以前计算机显示器相对较小的时候,项目通常会有一个规则,即代码中的任何一行都不能超过 80 或 100 个字符,以便代码能够适合显示器。这种规则已经不那么常见了。通常在 Python 中,最简单的做法就是让长行保持长。

但是,如果一行太长,难以阅读或处理,则可以使用以下几种技巧将长行拆分为较短的独立行。

参数分解线

假设有一个函数调用行,由于参数很多所以很长,如下所示:

绘制背景形状(selected_shape.x,selected_shape.y,子宽度+边距,子高度*边距,selected_color)

为了分解这一长行,请在逗号后添加换行符,并缩进后面的行,以便参数具有与上面的参数相同的缩进,如下所示:

绘制背景形状(selected_shape.x,selected_shape.y,
                      子宽度+边距,子高度*边距,
                      selected_color)

用括号分隔长行

如果 Python 发现一行带有左括号(而没有匹配的右括号,Python 会将后面的行视为第一行的延续,直到匹配成功。和也 )适用。[{

例如,假设有这个长的 if 测试:

如果 selected_x >= 0 且 selected_x < shape.width 且 selected_y >= 0 且 selected_y < shape.height:
   返回 True

较长的测试表达式可以分成几行,用一对括号括起来。第二行及之后的行应再缩进4个空格,这样它们就不会意外地与后续的主体行对齐。

如果 (selected_x >= 0 且
        selected_x < shape.width 且 # 额外缩进
        selected_y >= 0 且
        selected_y < shape.height):
   返回 True

还有一种偏好是,每行的最后一个单词都是操作符,比如and+,这样就强化了后面几行有更多内容的想法。

命名参数异常

项间 1 个空格规则有一个例外,但这种情况很少见。如果函数调用有命名参数,则不需要像这样在周围留空格=

打印('嗨',结束='')

我认为这里的原因是,这种用法=与更常见的变量赋值不同=,所以最好让这种用法看起来有点不同。


命名怪癖:

Python 关键字

一些词,例如deffor和 ,if是 Python 中的固定“关键字”,因此您不能使用这些词作为变量或函数名称。以下是关键字列表:

>>>导入关键字
>>> keyword.kwlist 
['False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']

“len” 规则:不要使用内置函数作为变量名

Python 有许多内置函数,例如len()min()。作为 Python 灵活性的一个奇怪例子,您的代码可以使用赋值=来更改len代码中的含义……这可能是一个巨大的错误!

>>> len('hello')   # len 函数有效
5 
>>> len = 7        # 将“len”重新定义为 7,这不是个好主意
>>> len('hello')   # 哦不!
TypeError: 'int' 对象不可调用

这里有一个简单的规则:不要使用常用函数的名称作为变量名。以下是最常见的函数名称:

len abs min max int float list str dict 范围 map 过滤器格式

不需要记住所有要避免使用的函数名称列表,只需避免使用代码中使用的函数名称,通常是众所周知的函数,如、、len等等。 rangemin

顺便说一句,这就是为什么我们避免使用“str”或“list”作为变量名,而是使用“s”和“lst”。

以这种方式重新定义函数只会影响您的本地代码,而不会影响程序中其他地方的代码。因此,如果您的代码意外定义了名为 的变量divmod,则不会干扰调用内置函数 的另一个函数中的代码divmod()

一个关于可读性的小笑话

对于读到这里的人来说,这是一个可选点。可读性是什么意思?可以说它意味着代码的视觉效果与它要执行的操作的语义相符。

考虑到这一点,您如何看待这段计算总分但间距在技术上违反 PEP8 的代码:

总分 = 分数*10 + 奖励*2

我认为它看起来还不错。虽然没有空格,但缺少的空格与优先级一致——乘法将首先发生,而缺少的空格在某种程度上强化了这一点。

这个版本怎么样?

总分 = 分数 * 10+奖金 * 2

看到这个,你可能会笑出声来或者皱眉头。这完全是错的,有点像笑话的妙语。这可能会让你稍微明白,代码的含义和它的外观有着某种深层次的联系。考虑到这种联系,看起来杂乱的代码更容易产生混淆和错误也许并不奇怪。

  • 11
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值