zl程序教程

您现在的位置是:首页 >  后端

当前栏目

十年Python老鸟总结的5条Python开发最佳实践

Python开发 总结 实践 最佳 十年 老鸟
2023-09-11 14:19:30 时间

Python是一门动态语言。动态性为Python带来了巨大的灵活性和表达力。但是任何事物都有两面性,动态性给Python带来强大能力的同时也带来了一些混乱,因此我们在开发过程中最好遵循某种最佳实践,以确保少犯错、不犯错。作为一个做了十几年Python开发的老鸟,为大家总结出5条Python开发最佳实践。

在这里插入图片描述

关于Python中常犯的错误、常掉的坑,我整理了另外一系列文章,大家可以移步到
Python避坑指南Python避坑指南(续) 阅读。

不要用索引遍历序列

不要这样做

for i in range(len(tab)):
	print(tab[i])

建议这样做

for elem in tab:
	print(elem)

如果同时需要索引和元素,请用enumerate

for i, elem in enumerate(tab):
	print((i, elem))

谨慎使用 "=="判断真假

if (var == True):
	# 当var为True或1(包括1.0, 1L)时上面条件判断为True
    
if (var != True):
	# 当var不为True或1时上面条件判断为True

if (var == False):
	# 当var为False或0 (包括0.0, 0L, 0j)时上面条件判断为True

if (var == None):
	# 当var为None时上面条件判断为True

if var:
	# 当var为非空字符串/列表/字典/元组以及True和非0值时上面判断条件为True

if not var:
	# 当var为 "", {}, [], (), 0, None, False时上面判断条件为True

if var is True:
	# 当var为布尔值True时上面判断条件为True

if var is False:
	# 当var为布尔值False时上面判断条件为True

if var is None:
    # 当var为None时上面条件判断为True

善用错误处理

Python圈里有句至理名言:“请求宽恕易,请求许可难”(“It’s easier to ask for forgiveness than permission”)

不要这样做

if os.path.isfile(file_path):
	file = open(file_path)
else:
	# do something

建议这样做

try:
	file = open(file_path)
except OSError as e:
	# do something

如果你用的Python版本为2.6+,那么用with替代try…except…finally可以进一步提升代码的易用性和简洁性。

with open(file_path) as file:

with 语句实现原理建立在上下文管理器之上。上下文管理器是一个实现 __enter____exit__ 方法的类。使用 with 语句确保在嵌套块的末尾调用 __exit__ 方法。这个概念类似于 try...finally 块的使用,但用with语句不用关心如何做保护,只需要关心可能面临的异常即可。

善用"鸭子类型"

Python是一门动态语言,因此类型检查会失去Python的这种灵活性优势。相反,我们应该用鸭子类型类检测行为。如果你希望得到一个字符串,那么就用str()将对象转换为字符串;如果你希望得到一个列表,那么就用list()将可迭代对象转换成列表。

不要这样做

def foo(name):
	if isinstance(name, str):
	print(name.lower())
    
def bar(listing):
	if isinstance(listing, list):
	listing.extend((1, 2, 3))
	return ", ".join(listing)

推荐这样做

def foo(name) :
	print(str(name).lower())
    
def bar(listing) :
	l = list(listing)
	l.extend((1, 2, 3))
	return ", ".join(l)

用上面的代码,函数foo()支持传入一切对象;函数bar()支持传入字符串、元组、集合、列表…等一切可迭代类型。更加符合DRY(Don’t Repeat Yourself)原则。

不要在__init__之外初始化成员变量

很多其他语言(尤其是Java和PHP)转Python的开发者会习惯性地将成员变量写在类名下方,并赋予默认值。这样做在Python中虽然不会报错,但程序行为可能给你预期的不一样。这样定义的变量是类属性(静态变量)。

这意味着2大危害:

  1. 如果类属性发生改变,那么初始值也会变;
  2. 如果设置的初始值是一个可变对象,那么这个变量在实例间是共享的。

不要这样做(除非定义静态变量)

class Car(object):
	color = "red"
	wheels = [Wheel(), Wheel(), Wheel(), Wheel()]

推荐这样做

class Car(object):
	def __init__(self):
		self.color = "red"
		self.wheels = [Wheel(), Wheel(), Wheel(), Wheel()]

总结

以上5条,只要大家在开发中能严格遵守,写出的代码无论是健壮性还是可维护性都会更行一层楼。