: | : | :期货程序化 | :期货程序化研究 | :期货量化学习 | :期货量化 |
返回列表 发帖

Python代码这样写才规范优雅!

Python代码这样写才规范优雅!

我们在写 Python 代码时,有没有刻意注意过代码规范性呢?

一份不规范的代码不仅给自己培养了不好的习惯,由于 Python 理应是优雅的,不规范的代码不仅不够优雅,还影响了了阅读代码的可读性。更可怕的是不方便协作编程。

关于 Python 编程规范,可以学习 PEP 8 风格指南。

PEP 是 Python Enhancement Proposal 的缩写,通常翻译为“Python增强提案”。每个 PEP 都是一份为 Python 社区提供的指导 Python 往更好的方向发展的技术文档,其中的第 8 号增强提案(PEP 8)是针对 Python 语言编订的代码风格指南。

参考:

https://www.python.org/dev/peps/pep-0008/

Python PEP8编码规范的内容如下:
  1. 1. Introduction 介绍
  2. 2. A Foolish Consistency is the Hobgoblin of Little Minds 尽信书,则不如无书
  3. 3. Code lay-out 代码布局
  4. 3.1 Indentation 缩进
  5. 3.2 Tabs or Spaces? 制表符还是空格?
  6. 3.3 Maximum Line Length 行的最大长度
  7. 3.4 Should a line break before or after a binary operator? 在二元运算符之前应该换行吗?
  8. 3.5 Blank Lines 空行
  9. 3.6 Source File Encoding 源文件编码
  10. 3.7 Imports 导入
  11. 3.8 Module level dunder names 模块级的“呆”名
  12. 4. String Quotes 字符串引号
  13. 5. Whitespace in Expressions and Statements 表达式和语句中的空格
  14. 5.1 Pet Peeves 不能忍受的事情
  15. 5.2 Other Recommendations 其他建议
  16. 6. Comments 注释
  17. 6.1 Block Comments 块注释
  18. 6.2 Inline Comments 行内注释
  19. 6.3 Documentation Strings 文档字符串
  20. 7. Naming Conventions 命名规范
  21. 7.1 Overriding Principle 最重要的原则
  22. 7.2 Descriptive: Naming Styles 描述:命名风格
  23. 7.3 Prescriptive: Naming Conventions 约定俗成:命名约定
  24. 7.4 Public and internal interfaces 公共和内部的接口
  25. 8. Programming Recommendations 编程建议
  26. 8.1 Function Annotations 功能注释
  27. 9. 参考
复制代码
1. Introduction 介绍

本文提供的 Python 代码编码规范基于 Python 主要发行版本的标准库。Python 的 C 语言实现的 C 代码规范请查看相应的 PEP 指南。

这篇文档以及PEP 257(文档字符串的规范)改编自 Guido 原始的《Python Style Guide》一文,同时添加了一些来自 Barry 的风格指南。

这篇规范指南随着时间的推移而逐渐演变,随着语言本身的变化,过去的约定也被淘汰了。

许多项目有自己的编码规范,在出现规范冲突时,项目自身的规范优先。

2. A Foolish Consistency is the Hobgoblin of Little Minds 尽信书,则不如无书

Guido的一条重要的见解是代码阅读比写更加频繁。这里提供的指导原则主要用于提升代码的可读性,使得在大量的Python代码中保持一致。就像PEP20提到的,“Readability counts”。

这是一份关于一致性的风格指南。这份风格指南的风格一致性是非常重要的。更重要的是项目的风格一致性。在一个模块或函数的风格一致性是最重要的。

然而,应该知道什么时候应该不一致,有时候编码规范的建议并不适用。当存在模棱两可的情况时,使用自己的判断。看看其他的示例再决定哪一种是最好的,不要羞于发问。

特别是不要为了遵守PEP约定而破坏兼容性!

几个很好的理由去忽略特定的规则:

当遵循这份指南之后代码的可读性变差,甚至是遵循PEP规范的人也觉得可读性差。

与周围的代码保持一致(也可能出于历史原因),尽管这也是清理他人混乱(真正的Xtreme Programming风格)的一个机会。

有问题的代码出现在发现编码规范之前,而且也没有充足的理由去修改他们。

当代码需要兼容不支持编码规范建议的老版本Python。

3 Code lay-out 代码布局

3.1 Indentation 缩进

每一级缩进使用4个空格。

续行应该与其包裹元素对齐,要么使用圆括号、方括号和花括号内的隐式行连接来垂直对齐,要么使用挂行缩进对齐。当使用挂行缩进时,应该考虑到第一行不应该有参数,以及使用缩进以区分自己是续行。
  1. #推荐的写法:

  2. # 与左括号对齐
  3. foo = long_function_name(var_one, var_two,
  4.                          var_three, var_four)

  5. # 用更多的缩进来与其他行区分
  6. def long_function_name(
  7.         var_one, var_two, var_three,
  8.         var_four):
  9.     print(var_one)

  10. # 挂行缩进应该再换一行
  11. foo = long_function_name(
  12.     var_one, var_two,
  13.     var_three, var_four)
复制代码
  1. #不推荐的写法:

  2. # 没有使用垂直对齐时,禁止把参数放在第一行
  3. foo = long_function_name(var_one, var_two,
  4.     var_three, var_four)

  5. # 当缩进没有与其他行区分时,要增加缩进
  6. def long_function_name(
  7.     var_one, var_two, var_three,
  8.     var_four):
  9.     print(var_one)
复制代码
四空格的规则对于续行是可选的。
  1. # 挂行缩进不一定要用4个空格
  2. foo = long_function_name(
  3.   var_one, var_two,
  4.   var_three, var_four)
复制代码
当if语句的条件部分长到需要换行写的时候,注意可以在两个字符关键字的连接处(比如if),增加一个空格,再增加一个左括号来创造一个4空格缩进的多行条件。这会与if语句内同样使用4空格缩进的代码产生视觉冲突。PEP没有明确指明要如何区分if的条件代码和内嵌代码。可使用的选项包括但不限于下面几种情况:
  1. # 没有额外的缩进
  2. if (this_is_one_thing and
  3.     that_is_another_thing):
  4.     do_something()

  5. # 增加一个注释,在能提供语法高亮的编辑器中可以有一些区分
  6. if (this_is_one_thing and
  7.     that_is_another_thing):
  8.     # Since both conditions are true, we can frobnicate.
  9.     do_something()

  10. # 在条件判断的语句添加额外的缩进
  11. if (this_is_one_thing
  12.         and that_is_another_thing):
  13.     do_something()
复制代码
在多行结构中的大括号/中括号/小括号的右括号可以与内容对齐单独起一行作为最后一行的第一个字符,就像这样:
  1. my_list = [
  2.     1, 2, 3,
  3.     4, 5, 6,
  4.     ]
  5. result = some_function_that_takes_arguments(
  6.     'a', 'b', 'c',
  7.     'd', 'e', 'f',
  8.     )
复制代码
或者也可以与多行结构的第一行第一个字符对齐,就像这样:
  1. my_list = [
  2.     1, 2, 3,
  3.     4, 5, 6,
  4. ]
  5. result = some_function_that_takes_arguments(
  6.     'a', 'b', 'c',
  7.     'd', 'e', 'f',
  8. )
复制代码
3.2 Tabs or Spaces? 制表符还是空格?

空格是首选的缩进方式。

制表符只能用于与同样使用制表符缩进的代码保持一致。

Python3不允许同时使用空格和制表符的缩进。

混合使用制表符和空格缩进的Python2代码应该统一转成空格。

当在命令行加入-t选项执行Python2时,它会发出关于非法混用制表符与空格的警告。当使用–tt时,这些警告会变成错误。强烈建议使用这样的参数。

3.3 Maximum Line Length 行的最大长度

所有行限制的最大字符数为79。

没有结构化限制的大块文本(文档字符或者注释),每行的最大字符数限制在72。

限制编辑器窗口宽度可以使多个文件并行打开,并且在使用代码检查工具(在相邻列中显示这两个版本)时工作得很好。

大多数工具中的默认封装破坏了代码的可视化结构,使代码更难以理解。避免使用编辑器中默认配置的80窗口宽度,即使工具在帮你折行时在最后一列放了一个标记符。某些基于Web的工具可能根本不提供动态折行。

一些团队更喜欢较长的行宽。如果代码主要由一个团队维护,那这个问题就能达成一致,可以把行长度从80增加到100个字符(更有效的做法是将行最大长度增加到99个字符),前提是注释和文档字符串依然以72字符折行。

Python标准库比较保守,需要将行宽限制在79个字符(文档/注释限制在72)。

较长的代码行选择Python在小括号,中括号以及大括号中的隐式续行方式。通过小括号内表达式的换行方式将长串折成多行。这种方式应该优先使用,而不是使用反斜杠续行。

反斜杠有时依然很有用。比如,比较长的,多个with状态语句,不能使用隐式续行,所以反斜杠是可以接受的:
  1. with open('/path/to/some/file/you/want/to/read') as file_1, \
  2.      open('/path/to/some/file/being/written', 'w') as file_2:
  3.     file_2.write(file_1.read())
复制代码
(请参阅前面关于多行if-语句的讨论,以获得关于这种多行with-语句缩进的进一步想法。)

另一种类似情况是使用assert语句。

确保在续行进行适当的缩进。

3.4 Should a line break before or after a binary operator? 在二元运算符之前应该换行吗?

几十年来,推荐的风格是在二元运算符之后中断。但是这会影响可读性,原因有二:操作符一般分布在屏幕上不同的列中,而且每个运算符被移到了操作数的上一行。下面例子这个情况就需要额外注意,哪些变量是相加的,哪些变量是相减的:
  1. # 不推荐: 操作符离操作数太远
  2. income = (gross_wages +
  3.           taxable_interest +
  4.           (dividends - qualified_dividends) -
  5.           ira_deduction -
  6.           student_loan_interest)
复制代码
为了解决这种可读性的问题,数学家和他们的出版商遵循了相反的约定。Donald Knuth在他的Computers and Typesetting系列中解释了传统规则:“尽管段落中的公式总是在二元运算符和关系之后中断,显示出来的公式总是要在二元运算符之前中断”。

遵循数学的传统能产出更多可读性高的代码:
  1. # 推荐:运算符和操作数很容易进行匹配
  2. income = (gross_wages
  3.           + taxable_interest
  4.           + (dividends - qualified_dividends)
  5.           - ira_deduction
  6.           - student_loan_interest)
复制代码
在Python代码中,允许在二元运算符之前或之后中断,只要本地的约定是一致的。对于新代码,建议使用Knuth的样式。

3.5 Blank Lines 空行

顶层函数和类的定义,前后用两个空行隔开。

类里的方法定义用一个空行隔开。

相关的功能组可以用额外的空行(谨慎使用)隔开。一堆相关的单行代码之间的空白行可以省略(例如,一组虚拟实现 dummy implementations)。

在函数中使用空行来区分逻辑段(谨慎使用)。

Python接受control-L(即^L)换页符作为空格;许多工具把这些字符当作页面分隔符,所以你可以在文件中使用它们来分隔相关段落。请注意,一些编辑器和基于Web的代码阅读器可能无法识别control-L为换页,将在其位置显示另一个字形。

3.6 Source File Encoding 源文件编码

Python核心发布版本中的代码总是以UTF-8格式编码(或者在Python2中用ASCII编码)。

使用ASCII(在Python2中)或UTF-8(在Python3中)编码的文件不应具有编码声明。

在标准库中,非默认的编码应该只用于测试,或者当一个注释或者文档字符串需要提及一个包含内ASCII字符编码的作者名字的时候;否则,使用\x,\u,\U , 或者 \N 进行转义来包含非ASCII字符。

对于Python 3和更高版本,标准库规定了以下策略(参见 PEP 3131):Python标准库中的所有标识符必须使用ASCII标识符,并在可行的情况下使用英语单词(在许多情况下,缩写和技术术语是非英语的)。此外,字符串文字和注释也必须是ASCII。唯一的例外是(a)测试非ASCII特征的测试用例,以及(b)作者的名称。作者的名字如果不使用拉丁字母拼写,必须提供一个拉丁字母的音译。

鼓励具有全球受众的开放源码项目采取类似的政策。

3.7 Imports 导入

导入通常在分开的行,例如:
  1. 推荐:
  2. import os
  3. import sys

  4. 不推荐:  
  5. import sys, os
复制代码
  1. 但是可以这样:
  2. from subprocess import Popen, PIPE
复制代码
  1. 导入总是位于文件的顶部,在模块注释和文档字符串之后,在模块的全局变量与常量之前。

  2. 导入应该按照以下顺序分组:

  3. 标准库导入

  4. 相关第三方库导入

  5. 本地应用/库特定导入

  6. 你应该在每一组导入之间加入空行。

  7. 推荐使用绝对路径导入,如果导入系统没有正确的配置(比如包里的一个目录在sys.path里的路径后),使用绝对路径会更加可读并且性能更好(至少能提供更好的错误信息):
复制代码
  1. import mypkg.sibling
  2. from mypkg import sibling
  3. from mypkg.sibling import example
复制代码
然而,显示的指定相对导入路径是使用绝对路径的一个可接受的替代方案,特别是在处理使用绝对路径导入不必要冗长的复杂包布局时:
  1. from . import sibling from .sibling import example
复制代码
标准库要避免使用复杂的包引入结构,而总是使用绝对路径。

不应该使用隐式相对路径导入,并且在Python3中删除了它。

当从一个包含类的模块中导入类时,常常这么写:
  1. from myclass import MyClass
  2. from foo.bar.yourclass import YourClass
复制代码
如果上述的写法导致名字的冲突,那么这么写:
  1. import myclass
  2. import foo.bar.yourclass
复制代码
然后使用“myclass.MyClass”和“foo.bar.yourclass.YourClass”。

避免通配符的导入(from import *),因为这样做会不知道命名空间中存在哪些名字,会使得读取接口和许多自动化工具之间产生混淆。对于通配符的导入,有一个防御性的做法,即将内部接口重新发布为公共API的一部分(例如,用可选加速器模块的定义覆盖纯Python实现的接口,以及重写那些事先不知道的定义)。

当以这种方式重新发布名称时,以下关于公共和内部接口的准则仍然适用。

3.8 Module level dunder names 模块级的“呆”名

像 __all__ ,  __author__,  __version__ 等这样的模块级“呆名“(也就是名字里有两个前缀下划线和两个后缀下划线),应该放在文档字符串的后面,以及除from  __future__  之外的import表达式前面。Python要求将来在模块中的导入,必须出现在除文档字符串之外的其他代码之前。

比如:
  1. """This is the example module.

  2. This module does stuff.
  3. """

  4. from __future__ import barry_as_FLUFL

  5. __all__ = ['a', 'b', 'c']
  6. __version__ = '0.1'
  7. __author__ = 'Cardinal Biggles'

  8. import os
  9. import sys
复制代码

论坛官方微信、群(期货热点、量化探讨、开户与绑定实盘)
 
期货论坛 - 版权/免责声明   1.本站发布源码(包括函数、指标、策略等)均属开放源码,用意在于让使用者学习程序化语法撰写,使用者可以任意修改语法內容并调整参数。仅限用于个人学习使用,请勿转载、滥用,严禁私自连接实盘账户交易
  2.本站发布资讯(包括文章、视频、历史记录、教材、评论、资讯、交易方案等)均系转载自网络主流媒体,内容仅为作者当日个人观点,本网转载此文出于传递更多信息之目的,并不意味着赞同其观点或证实其描述。本网不对该类信息或数据做任何保证。不对您构成任何投资建议,不能依靠信息而取代自身独立判断,不对因使用本篇文章所诉信息或观点等导致的损失承担任何责任。
  3.本站发布资源(包括书籍、杂志、文档、软件等)均从互联网搜索而来,仅供个人免费交流学习,不可用作商业用途,本站不对显示的内容承担任何责任。请在下载后24小时内删除。如果喜欢,请购买正版,谢谢合作!
  4.龙听期货论坛原创文章属本网版权作品,转载须注明来源“龙听期货论坛”,违者本网将保留追究其相关法律责任的权力。本论坛除发布原创文章外,亦致力于优秀财经文章的交流分享,部分文章推送时若未能及时与原作者取得联系并涉及版权问题时,请及时联系删除。联系方式:http://www.qhlt.cn/thread-262-1-1.html
如何访问权限为100/255贴子:/thread-37840-1-1.html;注册后仍无法回复:/thread-23-1-1.html;微信/QQ群:/thread-262-1-1.html;网盘链接失效解决办法:/thread-93307-1-1.html

如何访问权限为100/255贴子:/thread-37840-1-1.html;注册后仍无法回复:/thread-23-1-1.html;微信/QQ群:/thread-262-1-1.html;网盘链接失效解决办法:/thread-93307-1-1.html

TOP

返回列表