60D1 – Python 特性与基本语法

基本语法

变量命名规则、缩进原则、特殊关键字、特殊运算符等。

命名规则

Python 的变量命名规则主要包括两条:

  • 允许包括英文、数字以及下划线(_),不能以数字开头
  • 名称区分大小写

特别说明,以“下划线”开头的变量是有特殊意义的:

  • 类变量如果以下划线开头,代表不能直接被访问。
    类似于 C# 受保护型变量(protected),表示不能通过 import module_-name 导入。
  • 类变量如果以双下划线开头,表示为类的私有成员,不能被导入和其他类变量访问。
  • 以双下划线开头和双下划线结尾的变量是 Python 里的专用标识,有特殊身份。

如 Python 自定义类中都包括 __init__ 和 __add__ 方法,如果不重写 __add__ 去执行两个类加法操作,程序会抛出 TypeError 异常。只有重写后程序才能正常执行加法操作。

Python 变量命名习惯一般遵守蛇形命名法(Snake Case):

变量名由多个部分组成,每个部分之间使用下划线 _ 进行连接,所以也称之为 下划线命名法。

引用自 大专栏 —— 编程命名规则
  • 一般变量命名,book_id、book_store_count;
  • 类名的首字母为大写,如 Python 内置模块 collections.abc 中的 lterable 类,我们自定义为 Book 类等;
  • 类的方法命名:get_store_count();
  • 其他特殊变量,会全部大写:M)PI\MAX_VEHICLE_SPEED

缩进原则

Python 最具特色的地方就是用缩进代替 Java、C++ 中的大括号{},缩进的层级结构表示代码的逻辑层次。

比如,自定义一个 Book 类 ,重写 __add__ 方法进行计算两类书的库存总和。

Python 的缩进方法一般为 4 个字符。

  • 代码行 class Book(object) 与 代码行 # 定义类的参数 的缩进,此处为 4 个字符;
  • 代码行 def __add__(self, book): 与 return 所在行缩进也是 4 个字符。

通过这种层级结构,展现代码的逻辑层次。

我们通过下面的代码来创建一个 Book 类:

class Book(object):
	# 定义类的参数  
	def __init__(self, book_id, book_name, book_store_count):
		self.book_id = book_id
		self.book_name = book_name
		self.book_store_count = book_store_count
	# 重写加法操作  
	def __add__(self, book):
		return self.book_store_count + book_store_count
	
# 创建两个 Book 类  
python_into_book = Book(1, 'Python入门', 100)
saga_intro_book - Book(2, 'SAGA站点介绍', 200)
# 求两本书的销量  
sales_cnt = python_intro_book + saga_intro_book
print(sales_cnt) # => 300

可知打印销量为300。

缩进格式

  • 每一级缩进使用4个空格。
  • 续行应该与其包裹元素对齐,要么使用圆括号、方括号和花括号内的隐式行连接来垂直对齐,要么使用挂行缩进对齐
  • 当使用挂行缩进时,应该考虑到第一行不应该有参数,以及使用缩进以区分自己是续行。

行的最大长度

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

空行

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

Imports 导入

  • 导入通常在分开的行,例如:
# 推荐:  
	import os

	import sys

# 不推荐:  
	import sys, os

# 也可以:  
	from subprocess import Popen, PIPE
  • 导入总是位于文件的顶部,在模块注释和文档字符串之后,在模块的全局变量与常量之前。
  • 导入应该按照以下顺序分组:
    1. 标准库导入
    2. 相关第三方库导入
    3. 本地应用/库特定导入
    4. 你应该在每一组导入之间加入空行。
  • 推荐使用绝对路径导入,如果导入系统没有正确的配置(比如包里的一个目录在 sys.path 里的路径后),使用绝对路径会更加可读并且性能更好(至少能提供更好的错误信息)

Comments 注释

  • 与代码相矛盾的注释比没有注释还糟,当代码更改时,优先更新对应的注释!
  • 注释应该是完整的句子。如果一个注释是一个短语或句子,它的第一个单词应该大写,除非它是以小写字母开头的标识符(永远不要改变标识符的大小写!)。
  • 如果注释很短,结尾的句号可以省略。块注释一般由完整句子的一个或多个段落组成,并且每句话结束有个句号。
  • 在句尾结束的时候应该使用两个空格。
  • 当用英文书写时,遵循Strunk and White (译注:《Strunk and White, The Elements of Style》)的书写风格。
  • 在非英语国家的Python程序员,请使用英文写注释,除非你120%的确信你的代码不会被使用其他语言的人阅读。

Block Comments 块注释

  • 块注释通常适用于跟随它们的某些(或全部)代码,并缩进到与代码相同的级别。块注释的每一行开头使用一个#和一个空格(除非块注释内部缩进文本)。
  • 块注释内部的段落通过只有一个#的空行分隔。

Inline Comments 行内注释

  • 有节制地使用行内注释。
  • 行内注释是与代码语句同行的注释。行内注释和代码至少要有两个空格分隔。注释由#和一个空格开始。
  • 事实上,如果状态明显的话,行内注释是不必要的,反而会分散注意力。
# 比如说,这种就不需要注释:  
	x = x + 1                # Increment x

# 但有时,这样注释又很有用:  
	x = x + 1                # Compensate for border

Documentation Strings 文档字符串

  • 要为所有的公共模块,函数,类以及方法编写文档说明。
  • 非公共的方法没有必要,但是应该有一个描述方法具体作用的注释。这个注释应该在def那一行之后。
  • PEP 257 描述了写出好的文档说明相关的约定。特别需要注意的是,多行文档说明使用的结尾三引号应该自成一行,例如:
"""Return a foobang

Optional plotz says to frobnicate the bizbaz first.

"""
  • 对于单行的文档说明,尾部的三引号应该和文档在同一行。

约定俗成的命名约定

Names to Avoid 应避免的名字

  • 永远不要使用字母‘l’(小写的L),‘O’(大写的O),或者‘I’(大写的I)作为单字符变量名。
  • 在有些字体里,这些字符无法和数字0和1区分,如果想用‘l’,用‘L’代替。

Class Names 类名

  • 类名一般使用首字母大写的约定。
  • 在接口被文档化并且主要被用于调用的情况下,可以使用函数的命名风格代替。
  • 注意,对于内置的变量命名有一个单独的约定:大部分内置变量是单个单词(或者两个单词连接在一起),首字母大写的命名法只用于异常名或者内部的常量。

Function Names 函数名

  1. 函数名应该小写,如果想提高可读性可以用下划线分隔。
  2. 大小写混合仅在为了兼容原来主要以大小写混合风格的情况下使用(比如 threading.py),保持向后兼容性。

Function and method arguments 函数和方法参数

  • 始终要将 self 作为实例方法的的第一个参数。
  • 始终要将 cls 作为类静态方法的第一个参数。
  • 如果函数的参数名和已有的关键词冲突,在最后加单一下划线比缩写或随意拼写更好。因此 class_ 比 clss 更好。(也许最好用同义词来避免这种冲突)

Programming Recommendations 编程建议

  • 代码应该用不损害其他Python实现的方式去编写(PyPy,Jython,IronPython,Cython,Psyco 等)。
    比如,不要依赖于在 CPython 中高效的内置字符连接语句 a += b 或者 a = a + b。这种优化甚至在 CPython 中都是脆弱的(它只适用于某些类型)并且没有出现在不使用引用计数的实现中。在性能要求比较高的库中,可以种 “.join() 代替。这可以确保字符关联在不同的实现中都可以以线性时间发生。
  • 和像None这样的单例对象进行比较的时候应该始终用 is 或者 is not,永远不要用等号运算符。
    另外,如果你在写 if x 的时候,请注意你是否表达的意思是 if x is not None。举个例子,当测试一个默认值为 None 的变量或者参数是否被设置为其他值的时候。这个其他值应该是在上下文中能成为 bool 类型 false 的值。
  • 使用 is not 运算符,而不是 not … is 。虽然这两种表达式在功能上完全相同,但前者更易于阅读,所以优先考虑。
# 推荐: 
	if foo is not None

# 不推荐:
	if not foo is None:
页面: 1 2 3 4

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注