新手入门Python编程的8个实用建议


Posted in Python onJuly 12, 2019

前言

我们在用Python进行机器学习建模项目的时候,每个人都会有自己的一套项目文件管理的习惯,我自己也有一套方法,是自己曾经踩过的坑踩过的雷总结出来的,现在在这里分享一下给大家,因为很多伙伴是接触Python编程入门不久,也希望大家少走弯路,多少有些地方可以给大家借鉴。

目录先放出来

  • 项目文件事先做好归档
  • 永远不要手动修改源数据并且做好备份
  • 做好路径的正确配置
  • 代码必要的地方做好备注与说明
  • 加速你的Python循环代码
  • 可视化你的循环代码进度
  • 使用高效的异常捕获工具
  • 要多考虑代码健壮性

1. 项目文件事先做好归档

每次开始一个新工作的时候,以前的我总是贪图方便,Code、Data、文档都集中放在一个文件夹内,看起来很乱,一度让回溯过程十分痛苦,或者是换了部电脑,文件全都运行不行了,需要自行修改路径,十分痛苦。

经过自己一番探索,大家可以大致将项目分成几个子文件夹,code放在主文件夹里:

新手入门Python编程的8个实用建议

2. 永远不要手动修改源数据并且做好备份

我们需要对源数据进行好备份,方便我们下一次进行回溯,可以进行下一步的操作或者是对中间步骤的修改,而且,对代码等其他文件也是需要做好备份的,以免出现意外丢失。

这里来自良许Linux 的一篇文章,推荐了4个工具:

  • Git版本控制系统
  • Rsync文件备份
  • Dropbox云存储
  • Time Machine时光机器

更多的工具介绍和使用我这边就不展开,大家可以去自行了解呗。

3. 做好路径的正确配置

很多同学在写路径的时候都很喜欢直接用绝对路径,虽然一般情况下不会有什么问题,但如果代码共享给其他人学习或者运行的时候,问题就来了,很多情况下都不能直接跑通,

这里建议:

  • 使用相对路径:脚本位于主目录下,其他资源(如数据、第三方包等)在其同级或低级目录下,如 ./data/processed/test1.csv
  • 全局路径配置变量:
# 设置主目录
HOME_PATH = r'E:ML90615- PROJECT1'
# 读取数据
data = open(HOME_PATH+'/data/processed/test1.csv')
data = pd.read_csv(data)
data.head()

4. 代码必要的地方做好备注与说明

这个我相信大多数人都感同身受了,不信?拿回一个月前自己写的代码看看吧,看一下能看懂多少(如果没有做好备注说明的话)

5. 加速你的Python循环代码

这里推荐 云哥(Python与算法之美)的一篇文章:24式加速你的python

收藏起来,多看多几次,养成好习惯呗,这样子你写代码才会越来越快~

6. 可视化你的循环代码进度

这里介绍一个Python库,tqdm,先安装一下:pip install tqdm

这个是一个可以显示循环进度的库,有了它就可以更加运筹帷幄了。

大家可以看下面的例子:

新手入门Python编程的8个实用建议

7. 使用高效的异常捕获工具

异常bug定位,以前的我经常也是一条print()函数走到底,虽然说也没什么问题,但效率上还是会比较慢,后来发现了一个叫PySnooper的装饰器,仿佛发现了新大陆。

我们一般debug,都是在我们可能觉得会有问题的地方,去打印输出,看下实际输出了什么,然后思考问题所在,这需要我们去改code,非常细致地改,相比较直接加个装饰器,是十分麻烦的。

大家可以看看Example:

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)

我们把函数每一步的输出都保存为file.log,我们可以直接去看到底哪里出了问题。

新手入门Python编程的8个实用建议

项目地址:https://github.com/cool-RR/pysnooper

8. 要多考虑代码健壮性

何为代码的健壮性,顾名思义,就是可以抵挡得住各种异常场景的测试,异常处理工作由“捕获”和“抛出”两部分组成。“捕获”指的是使用 try ... except 包裹特定语句,妥当的完成错误流程处理。而恰当的使用 raise 主动“抛出”异常,更是优雅代码里必不可少的组成部分,下面总结几点供大家参考:

1)知道要传入的参数是什么,类型,个数 (异常处理,逻辑判断)

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'))

2)只做最精准的异常捕获

我们有的时候想着让脚本work才是王道,所以不管三七二十一就搞一个大大的try...except把整块代码包裹起来,但这样很容易把原本该被抛出的 AttibuteError 吞噬了。从而给我们的 debug 过程增加了不必要的麻烦。

所以,我们永远只捕获那些可能会抛出异常的语句块,而且尽量只捕获精确的异常类型,而不是模糊的 Exception。

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

3)异常处理不应该喧宾夺主

像上一条说到的异常捕获要精准,但如果每一个都很精准的话,其实我们的代码里就会有很多try...except语句块,以至于扰乱核心代码,代码整体阅读性。

这里,我们可以利用上下文管理器来改善我们的异常处理流程,简化重复的异常处理逻辑。

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

在上面的代码里,我们定义了一个名为 raise_api_error 的上下文管理器,它在进入上下文时什么也不做。但是在退出上下文时,会判断当前上下文中是否抛出了类型为 self.captures 的异常,如果有,就用 APIErrorCode 异常类替代它。

使用上下文管理器后,简洁的代码如下:

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({})

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
优化Python代码使其加快作用域内的查找
Mar 30 Python
Python实现计算文件夹下.h和.cpp文件的总行数
Apr 23 Python
python使用urllib2实现发送带cookie的请求
Apr 28 Python
详解Python中表达式i += x与i = i + x是否等价
Feb 08 Python
python中实现k-means聚类算法详解
Nov 11 Python
Django的HttpRequest和HttpResponse对象详解
Jan 26 Python
python pandas 组内排序、单组排序、标号的实例
Apr 12 Python
python框架django项目部署相关知识详解
Nov 04 Python
python爬虫库scrapy简单使用实例详解
Feb 10 Python
python GUI库图形界面开发之PyQt5树形结构控件QTreeWidget详细使用方法与实例
Mar 02 Python
解决redis与Python交互取出来的是bytes类型的问题
Jul 16 Python
详解appium自动化测试工具(monitor、uiautomatorviewer)
Jan 27 Python
python读取并写入mat文件的方法
Jul 12 #Python
numpy数组广播的机制
Jul 12 #Python
Python的numpy库下的几个小函数的用法(小结)
Jul 12 #Python
python读取.mat文件的数据及实例代码
Jul 12 #Python
如何用Python破解wifi密码过程详解
Jul 12 #Python
python pip源配置,pip配置文件存放位置的方法
Jul 12 #Python
Python3 itchat实现微信定时发送群消息的实例代码
Jul 12 #Python
You might like
php+jquery编码方面的一些心得(utf-8 gb2312)
2010/10/12 PHP
PHP中读写文件实现代码
2011/10/20 PHP
163的邮件用phpmailer发送(实例详解)
2013/06/24 PHP
Laravel5.* 打印出执行的sql语句的方法
2017/07/24 PHP
PHP后期静态绑定实例浅析
2018/12/21 PHP
jQuery 常见开发使用技巧总结
2009/12/26 Javascript
百度Popup.js弹出框进化版 拖拽小框架发布 兼容IE6/7/8,Firefox,Chrome
2010/04/13 Javascript
让低版本浏览器支持input的placeholder属性(js方法)
2013/04/03 Javascript
js中数组Array的一些常用方法总结
2013/08/12 Javascript
javascript:FF/Chrome与IE动态加载元素的区别说明
2014/01/26 Javascript
JavaScript分页功能的实现方法
2015/04/25 Javascript
Jquery-1.9.1源码分析系列(十一)之DOM操作
2015/11/25 Javascript
微信小程序 保留小数(toFixed)详细介绍
2016/11/16 Javascript
JavaScript实现经典排序算法之选择排序
2016/12/28 Javascript
Js面试算法详解
2018/04/08 Javascript
echarts实现地图定时切换散点与多图表级联联动详解
2018/08/07 Javascript
JavaScript如何把两个数组对象合并过程解析
2019/10/10 Javascript
前端性能优化建议
2020/09/17 Javascript
[03:57]《不朽》——2015DOTA2国际邀请赛—中国军团出征主题曲MV
2015/07/15 DOTA
如何利用Fabric自动化你的任务
2016/10/20 Python
Python3使用pandas模块读写excel操作示例
2018/07/03 Python
pyspark操作MongoDB的方法步骤
2019/01/04 Python
Python判断变量名是否合法的方法示例
2019/01/28 Python
pyqt5 comboBox获得下标、文本和事件选中函数的方法
2019/06/14 Python
Python循环中else,break和continue的用法实例详解
2019/07/11 Python
Django上使用数据可视化利器Bokeh解析
2019/07/31 Python
详解python tkinter 图片插入问题
2020/09/03 Python
HTML5 File API改善网页上传功能
2009/08/19 HTML / CSS
波兰最早的运动鞋精品店之一:Street Supply
2019/08/29 全球购物
Java中实现多态的机制是什么?
2014/12/07 面试题
员工生日活动方案
2014/08/24 职场文书
实验心得体会
2014/09/05 职场文书
生日赠语
2015/06/23 职场文书
消防安全主题班会
2015/08/12 职场文书
详解python中[-1]、[:-1]、[::-1]、[n::-1]使用方法
2021/04/25 Python
面试中老生常谈的MySQL问答集锦夯实基础
2022/03/13 MySQL