优化python程序的建议

优化python程序的建议

1 将常量集中到一个(配置)文件

2 行长度

每行不超过80个字符

以下情况除外:

1)长的导入语句

2)注释里的url

3 不要用反斜杠连接行

python中会将圆括号、中括号和花括号将行隐式连接起来,因此,你可以再表达式外面增加一对额外的圆括号。

示例:

if(width == 0 and height == 0 and color == 'red' and emphasis == 'strong'):

4 括号

宁缺毋滥的使用括号

除非是用于实现行连接, 否则不要在返回语句或条件语句中使用括号. 不过在元组两边使用括号是可以的.

Yes: if foo: bar() while x: x = bar() if x and y: bar() if not x: bar() return foo for (x, y) in dict.items(): ...
No: if (x): bar() if not(x): bar() return (foo)

5 空行

顶级定义之间空两行,方法定义之间空一行

顶级定义:函数或者类定义

类定义与第一个方法之间,应该空一行

函数或者方法中,某些地方要是你觉得合适,就空一行

6 空格

括号内不要有空格

yes: spam(ham[1], {egg: 2}, [])
no: spam( ham[ 1 ], { egg:2 }, [ ] )

不要在逗号、分号、冒号前面加空格,但应该在他们后面加(除了在行尾)。

yes: if x == 4: print x, y
no: if x == 4 : print x , y

参数列表,索引或者切片的左括号前不加空格

yes: spam(1)
no: spam (1)

yes: dict["key"] = list[index]
no: dict["key"] = list [index]

在二元操作符两边都加上一个空格,比如赋值(=),比较(==, <, >, !=, in not in , is , is not),布尔(and, or, not)

至于算术操作符两边的空格如何使用,需要自己判断,但是两侧务必要保持一致

yes: x == 1
no: x<1

当“=”用于指示关键字参数或者默认参数时,不要在其两侧使用空格

yes: def complex(real, imag=0.0): return magic(r=real, i=img)
no:  def complex(real, imag = 0.0): return magic(r = real, i = img)

不用使用空格来垂直对齐多行间的标记,因为这会造成维护的负担(适用于:, #, =等)

yes: foo = 1000 # 注释 long_name = 2 #注释不需要对齐

7 新文件的创建

新文件的创建开始以:#coding:utf-8开头

8 main

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

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

def main():
	if __name__ == "__main__":
		...

所有顶级代码在模块导入时都会被执行,要小心不要去调用函数,创建对象,或者执行那些不应该在使用pydoc时执行的操作。

9 python之父Guido推荐的命名规范

typepuclicinternal
classesCapWords_CapWords
moduleslower_with_under_lower_with_under
packageslower_with_under
exceptionCapWords
functionslower_with_under()_lower_with_under()
global/class contantsCAPS_WITH_UNDER_CAPS_WITH_UNDER
global/class varibleslower_with_under_lower_with_under
instance variableslower_with_under_lower_with_under
method nameslower_with_under
function parameterslower_with_under
local variableslower_with_under

10 语句

通常一个语句应该占一行

不过,如果测试结果与测试语句在一行放得下,可以将它们放在一行。

如果是if语句,只在没有else时才能这样做。特别地,绝不要对try/except这样做,因为try和except不能放在同一行

yes: if foo: bar(foo)
no: if foo: bar(foo) else: baz(foo)
no: try: bar(foo) except ValueError: baz(foo)

11 导入格式

每个导入独占一行

yes:
	import sys
    import os
no: import sys, os  

导入总是放在文件的顶部,位于模块注释和文档字符串之后,模块全局变量和常量之前。

导入应该按照从最通用到最不通用的顺序分组:

1)标准库导入

2)第三方库导入

3)应用程序制定导入

import foo
from foo imort bar
import foo.bar import baz
from foo.bar import Quux
from Foob import ar

12 文件和sockets

在文件和sockets结束时,显示的关闭它。

除文件外,sockets或者其他类似文件对象在没有必要的情况下打开,会有许多副作用,例如:

1)它们可能会消耗有限的系统资源,如文件描述符。如果这些资源在使用后没有及时归还系统,那么处理这些对象的代码会将资源消耗殆尽;

2)持有文件将会阻止对于文件的其他诸如移动、删除之类的操作。

3)仅仅是从逻辑上关闭文件和sockets,那么他们仍然可能会被其共享的程序在无意中进行读或写操作,只有当它们真正被关闭后,对于它们尝试进行读写操作将会抛出异常,并使问题快速显现出来;

而且,幻想当文件对象析构时,文件和sockets会自动关闭,试图将文件对象的生命周期和文件的状态绑定在一起的想法,都是不现实的。因为有如下的原因:

1)没有任何方法可以确保运行环境会真正地执行文件的析构,不同的python实现不同的内存管理技术,比如延时垃圾处理机制,延时垃圾处理机制可能会导致对象生命周期被任意无限制的延长;

2)对于文件意外的引用,会导致对于文件的持有时间超出预期(比如对于异常的跟踪,包含有全局变量等)

推荐使用“with 语句”来管理文件

with open(hello.txt") as f:
	for line in f:
		print line.strip()		

13 字符串

避免在循环中使用“+”或者“+=”来累加字符串,由于字符串是不可变的,这样做会创建大量不必要的临时对象,并且导致二次方而不是线性的运行时间。

作为替代方案,可以将每个字符串加入列表,然后循环结束后使用.join()连接变量

yes:
items = ['<table>']
for last_name, first_name in employee_list: 					        items.append('<tr><td>%s, %s</td></tr>' % (last_name, first_name)) 	
     items.append('</table>') 
employee_table = ''.join(items)

在同一个文件中,保持使用字符串引号的一致性,使用单引号或者双引号之一。在字符串内可以使用另外一种引号,以避免在字符串中使用。

14 类

​ 如果一个类不继承自其他类,就显示的从object继承,嵌套类也一样

yes:
class SampleClass(object):
	pass
class OuterClass(object):
	class InnerClass(object):
		pass
no:
class SampleClass:
	pass
class OuterClass:
	class InnerClass:
		pass

继承自object是为了使属性正常工作,并且这样可以保护你的代码,使其不受python 3000的一个特殊的潜在不兼容性影响,这样做也定义一些特殊的方法,这些方法实现了对象的默认语法,包括__new__,__init__, __delattr__, __getattribute__, __setattr__, __hash__, __repr__, and __str__.

15 注释

​ 确保对模块、函数、方法和行内注释使用正确的风格

16 文档字符串

​ python有一种独一无二的注释方式:使用文档字符串。文档字符串是包、模块、类或者函数里的第一条语句,这些字符串可以通过对象的__doc__成员被自动提取,并且被pydoc所用。我们对文档字符串的惯例是使用三重双引号"""。一个文档字符串应该这样组织:首先是一行以句号、问号或者惊叹号结尾的概述(或者该文档字符串只有一行),接着是一个空行,接着是文档字符串剩下的部分,它应该与文档字符串的第一行的第一个引号对齐

17 块注释和行注释

最需要协助是的是代码中哪些技巧性的部分,如果你在下次代码审查的时候必须解释一下,那么你应该现在就给它写注释,对于复杂的操作,应该在其操作开始前写上若干行注释,对于不是一目了然的代码,应该在其行尾添加注释。

为了提高代码的可读性民主是至少离开代码2个空格。

另一方面,绝对不要描述代码,假设读代码的人比你更懂python,他只是不知道你的代码要做什么

18 类注释

​ 类应该在其定义下有一个用于描述该类的文档字符串,如果你的类有公共属性,那么文档中应该有一个属性段,并且遵守和函数参数相同的格式

class SampleClass(object): 
	"""Summary of class here. Longer class information.... Longer class information.... Attributes: likes_spam: A boolean indicating if we like SPAM or not. eggs: An integer count of the eggs we have laid. """ 
	
	def __init__(self, likes_spam=False): 
		"""Inits SampleClass with blah.""" 
		self.likes_spam = likes_spam 
		self.eggs = 0 
		
	def public_method(self): 
		"""Performs operation blah."""

19 函数和方法注释

​ 一个函数必须有文档字符串,除非它满足以下条件:

​ 1)外部不可见

​ 2)非常短小

​ 3)简单明了

​ 文档字符串应该包含函数做什么,以及输入和输出的详细描述,通常,不应该描述“怎么做”,除非是一些复杂的算法。文档字符串应该提供足够的信息,当别人编写代码调用该函数时,他不需要看一行代码,只要看文档字符串就可以了。对于复杂的代码,在代码旁加注释会比使用文档字符串更有意义。

​ 关于函数的几个方面应该在特定的小节中进行描述记录,这几个方面如下所述,每节应该以一个标题行开始,标题行以冒号结尾。除标题行,小节的其他内容应该被缩进2个空格。

​ Args:列出每个参数的名字, 并在名字后使用一个冒号和一个空格, 分隔对该参数的描述.如果描述太长超过了单行80字符,使用2或者4个空格的悬挂缩进(与文件其他部分保持一致). 描述应该包括所需的类型和含义.

​ 如果一个函数接受foo(可变长度参数列表)或者**bar (任意关键字参数), 应该详细列出foo和**bar.

​ Returns: (或者 Yields: 用于生成器)描述返回值的类型和语义. 如果函数返回None, 这一部分可以省略.

​ Raises:列出与接口有关的所有异常.

def fetch_bigtable_rows(big_table, keys, other_silly_variable=None): 
	"""Fetches rows from a Bigtable. Retrieves rows pertaining to the given keys from the Table instance represented by big_table. Silly things may happen if other_silly_variable is not None. 
	Args: big_table: An open Bigtable Table instance. 
	keys: A sequence of strings representing the key of each table row to fetch.
	ther_silly_variable: Another optional variable, that has a much longer name than the other args, and which does nothing. 
	Returns: A dict mapping keys to the corresponding table row data fetched. Each row is represented as a tuple of strings. 
	For example: {'Serak': ('Rigel VII', 'Preparer'), 'Zim': ('Irk', 'Invader'), 'Lrrr': ('Omicron Persei 8', 'Emperor')} 
	If a key from the keys argument is missing from the dictionary, then that row was not found in the table. 
	Raises: IOError: An error occurred accessing the bigtable.Table object. 
	""" 
	pass
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值