规范
1、项目文件事先做好归档
2、永远不要手动修改源数据并且做好备份
3、做好路径的正确配置
- 使用相对路径:脚本位于主目录下,其他资源(如数据、第三方包等)在其同级或低级目录下,如 ./data/processed/test1.csv
- 全局路径配置变量
4、代码必要的地方做好备注与说明
5、加速你的Python循环代码
6、使用高效的异常捕获工具,PySnooper的装饰器
import pysnooper
@pysnooper.snoop('./file.log')
def number_to_bits(number):
if number:
bits = []
while number:
number, remainder = divmod(number, 2)
bits.insert(0, remainder)
return bits
else:
return [0]
number_to_bits(6)
7、要多考虑代码健壮性,可以抵挡得住各种异常场景的测试
异常处理工作由
“捕获”: try … except 包裹特定语句
“抛出”:raise 主动“抛出”异常
- 知道要传入的参数是什么,类型,个数 (异常处理,逻辑判断)
def add(a, b):
if isinstance(a, int) and isinstance(b, int):
return a+b
else:
return '参数类型错误'
print(add(1, 2))
print(add(1, 'a'))
- 只做最精准的异常捕获
from requests.exceptions import RequestException
def save_website_title(url, filename):
try:
resp = requests.get(url)
except RequestException as e:
print(f'save failed: unable to get page content: {e}')
return False
# 这段正则操作本身就是不应该抛出异常的,所以我们没必要使用 try 语句块
# 假如 group 被误打成了 grop 也没关系,程序马上就会通过 AttributeError 来
# 告诉我们。
obj = re.search(r'<title>(.*)</title>', resp.text)
if not obj:
print('save failed: title tag not found in page content')
return False
title = obj.group(1)
try:
with open(filename, 'w') as fp:
fp.write(title)
except IOError as e:
print(f'save failed: unable to write to file {filename}: {e}')
return False
else:
return True
- 异常处理不应该喧宾夺主
我们可以利用上下文管理器来改善我们的异常处理流程,简化重复的异常处理逻辑
定义了一个名为 raise_api_error 的上下文管理器
class raise_api_error:
"""captures specified exception and raise ApiErrorCode instead
:raises: AttributeError if code_name is not valid
"""
def __init__(self, captures, code_name):
self.captures = captures
self.code = getattr(error_codes, code_name)
def __enter__(self):
# 该方法将在进入上下文时调用
return self
def __exit__(self, exc_type, exc_val, exc_tb):
# 该方法将在退出上下文时调用
# exc_type, exc_val, exc_tb 分别表示该上下文内抛出的
# 异常类型、异常值、错误栈
if exc_type is None:
return False
if exc_type == self.captures:
raise self.code from exc_val
return False
使用上下文管理器后,简洁的代码如下:
def upload_avatar(request):
"""用户上传新头像"""
with raise_api_error(KeyError, 'AVATAR_FILE_NOT_PROVIDED'):
avatar_file = request.FILES['avatar']
with raise_api_error(ResizeAvatarError, 'AVATAR_FILE_INVALID'),
raise_api_error(FileTooLargeError, 'AVATAR_FILE_TOO_LARGE'):
resized_avatar_file = resize_avatar(avatar_file)
with raise_api_error(Exception, 'INTERNAL_SERVER_ERROR'):
request.user.avatar = resized_avatar_file
request.user.save()
return HttpResponse({})
8、习惯
9、书写
- 常量名所有字母大写,由下划线连接各个单词如MAX_OVERFLOW,TOTAL
- 类:总是使用首字母大写单词串
- 函数:函数名应该为小写,可以用下划线风格单词以增加可读性