Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

【规范】Python编程规范 #13

Open
Valuebai opened this issue Feb 6, 2020 · 7 comments
Open

【规范】Python编程规范 #13

Valuebai opened this issue Feb 6, 2020 · 7 comments

Comments

@Valuebai
Copy link
Owner

Valuebai commented Feb 6, 2020

大公司规范

【知乎规范】强烈推荐:编码之前碎碎念(工程实践)https://python-web-guide.readthedocs.io/zh/latest/codingstyle/codingstyle.html

【Google规范】Google 开源项目风格指南:https://zh-google-styleguide.readthedocs.io/en/latest/google-python-styleguide/contents/

【Python Code Style】https://docs.python-guide.org/writing/style/

【Python最佳实践指南!】https://pythonguidecn.readthedocs.io/zh/latest/

image

PEP 8列出了许多细节,有几条规则绝对应该遵守:

Python官方有一个PEP8:Style Guide for Python Code。https://www.python.org/dev/peps/pep-0008/ 采用一致的代码风格,有利于项目的多人协作和后续的修改维护工作。Brett Slatkin写的《Effective Python》的第2条列举了一些PEP8中绝对应该遵守的规则。列举其中的一些(语言表述上和内容上我略有修改,是直接从我自己的笔记中复制出来):

空白

  • 使用空格space来表示缩进,而不要用制表符tab。
  • 和语法相关的每一层缩进都用4个空格来表示。
  • 每行的字符数不应超过79。
  • 对于占据多行的长表达式来说,除了首行之外的其他各行都应该在通常的缩进级别之上再加4个空格。
  • 文件中的函数与类之间应该用两个空行隔开。
  • 在同一个类中,各方法之间应该用一个空行隔开。
  • 在使用下标来获取列表元素、调用函数或给关键字参数赋值时,不要在两边添加空格。为变量赋值时,赋值符号的两边应各写上一个空格,且只写一个。

命名

  • 函数、变量及属性都应使用小写字母来拼写,各单词之间以下划线连接。例如lower_case。
  • 受保护的实例属性,应以单下划线开头,例如_leading_under。
  • 私有的实例属性,应以两个下划线开头,例如__double_leading。
  • 类与异常应以每个单词首字母大写的形式命名,例如CapitalizedWord。
  • 模块级别的常量应全部采用大写字母拼写,且用下划线连接,例如ALL_CAPS。
  • 类中的实例方法instance method应把首个参数命名为self来表示该对象自身。
  • 类方法class method的首个参数应命名为cls,以表示该类自身。

表达式和语句

  • 采用内联形式的否定词,而不要把否定词放在整个表达式的前面。例如应该写if a is not b而不是if not a is b。
  • 不要通过检测长度的方法来判断somelist是否为空值,应采用if not somelist这种方式来判断。标准的False、None、所有类型的数字0(包括浮点型、长整型和其他类型)、空序列(空字符串、元组和列表)以及空字典都为假。
  • 检测somelist是否为非空值时,也应采用if somelist的方式判断。
  • 不要编写单行的if语句、for循环和while循环及except复合语句,而应分成多行来写,以示清晰。
  • import语句应该总是放在文件开头。
  • 引入模块时,应使用绝对名称,而不是根据当前模块的路径来使用相对名称。例如引入bar包中的foo模块时,应使用from bar import foo,而不应简写为import foo。
  • 如果一定要以相对名称来缩写import语句时,应采用明确的写法from . import foo。
  • 文件中的import语句应该按顺序划分成三个部分,分别表示标准库模块、第三方模块以及自用模块。在每一部分中,各import语句应按模块的字母顺序排列。
@Valuebai
Copy link
Owner Author

Valuebai commented Feb 6, 2020

比如处理excel报表等直接用pandas提供的函数非常方便,我经常看见还是有人自己写一堆恶心的处理函数而不用pandas。如果自己造轮子确保测试和文档,否则后续维护和上手会有很大成本。

@Valuebai
Copy link
Owner Author

Valuebai commented Feb 6, 2020

用sentry等工具记录异常,有利于排查问题(能保存堆栈和现场信息)。切记不要轻易吞掉非预知异常,一旦出现问题不好排查,笔者之前维护的项目曾踩过坑,后来笔者引入了sentry排查问题方便很多。

@Valuebai
Copy link
Owner Author

Valuebai commented Feb 6, 2020

如果一个类不继承自其它类, 就显式的从object继承. 嵌套类也一样.

Yes: class SampleClass(object):
         pass


     class OuterClass(object):

         class InnerClass(object):
             pass


     class ChildClass(ParentClass):
         """Explicitly inherits from another class already."""

继承自 object 是为了使属性(properties)正常工作, 并且这样可以保护你的代码, 使其不受 PEP-3000 的一个特殊的潜在不兼容性影响. 这样做也定义了一些特殊的方法, 这些方法实现了对象的默认语义, 包括 new, init, delattr, getattribute, setattr, hash, repr, and str .

No: class SampleClass:
        pass


    class OuterClass:

        class InnerClass:
            pass

@Valuebai
Copy link
Owner Author

Valuebai commented Feb 6, 2020

每个导入应该独占一行

Yes: import os
     import sys

No:  import os, sys

@Valuebai
Copy link
Owner Author

Valuebai commented Feb 7, 2020

Main

即使是一个打算被用作脚本的文件, 也应该是可导入的. 并且简单的导入不应该导致这个脚本的主功能(main functionality)被执行, 这是一种副作用. 主功能应该放在一个main()函数中.

在Python中, pydoc以及单元测试要求模块必须是可导入的. 你的代码应该在执行主程序前总是检查 if name == 'main' , 这样当模块被导入时主程序就不会被执行.

def main():
      ...

if __name__ == '__main__':
    main()

@Valuebai
Copy link
Owner Author

Valuebai commented Feb 7, 2020

【命名规范】不知道怎么起名字,查询这个
https://unbug.github.io/codelf/

@Valuebai
Copy link
Owner Author

Valuebai commented Feb 8, 2020

【在列表/集合/字典中查找一个项】
有时我们需要在集合体中查找。让我们看看这两个选择:列表和集合(set)。

用如下代码举个例子:

s = set(['s', 'p', 'a', 'm'])
l = ['s', 'p', 'a', 'm']

def lookup_set(s):
    return 's' in s

def lookup_list(l):
    return 's' in l

即使两个函数看起来完全一样,但因为 查找集合 是利用了Python中的集合是可哈希的 特性,两者的查询性能是非常不同的。为了判断一个项是否在列表中,Python将会查看 每个项直到它找到匹配的项。这是耗时的,尤其是对长列表而言。另一方面,在集合中, 项的哈希值将会告诉Python在集合的哪里去查找匹配的项。结果是,即使集合很大,查询 的速度也很快。在字典中查询也是同样的原理。想了解更多内容,请见 StackOverflow 。想了解在每种数据结构上的多种常见操作的花费时间的详细内容, 请见 此页面。

因为这些性能上的差异,在下列场合在使用集合或者字典而不是列表,通常会是个好主意:

集合体中包含大量的项
您将在集合体中重复地查找项
您没有重复的项
对于小的集合体,或者您不会频繁查找的集合体,建立哈希带来的额外时间和内存的 开销经常会大过改进搜索速度所节省的时间。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant