Pegasus' Blog
保持一颗好奇心

Mastering Python Design Patterns

Patterns mean “I have run out of language.” - Rich Hickey

之前学习设计模式的时候总是没有什么感觉,因为记性不好一直没记住多少。python不像java中比较强调设计模式(编程套路),动态语言也内置了像是装饰器、迭代器等模式,另外python中的『一切皆对象』、鸭子类型等也导致python中实现的设计模式和其他语言有些差别。根据YAGNI(you aren’t gonna need it)和KISS(Keep it simple sutpid)原则,如果能用简单易懂的方式实现,最好不要滥用设计模式以免增加复杂度和维护难度。本博客是《Mastering Python Design Patterns》的读书笔记,涵盖大部分设计模式(力求pythonic实现),有兴趣可以参考下,代码示例版本为python3.5.2。(3.6都发布了,已经被时代遗弃😢……)

编写易维护的python项目

从实习到现在使用python也快两年了,虽然经验依旧不多,不过维护旧项目和开发新项目好歹也都经历过,记录下想法就当年终总结吧。很多东西是之前没参与项目协作的时候没有注意到的,要不就是踩了坑才知道的。和人协作项目以后才真正意识到代码首先是写给人看的,其次才是让机器执行的。

易编写,难维护

Always code as if the person who ends up maintaining your code is a violent psychopath who knows where you live.- John Woods

python做项目给我的感觉就是易编写,难维护。一方面是动态语言本身的特性,比如没有类型声明,难以重构等;另一方面就是团队流程和规范的问题,没有严格的流程控制提交代码的质量。目前很多使用python的公司都是小公司,很多流程不正规,没有编码规范,没有文档,没有注释,没有静态检测(pylint),没有code review,没有单元测试,没有持续集成等等,最终的代码质量可想而知,维护和新人上手成本很高,代码仓库很容易失控(野蛮开发技术债会越积越多)。一开始我认为python号称『伪代码』语言,应该是更易读易理解的,后来发现我错了。python给你一种代码很好写的错觉,很容易就写出烂代码。

I think a lot of new programmers like to use advanced data structures and advanced language features as a way of demonstrating their ability. I call it the lion-tamer syndrome. Such demonstrations are impressive, but unless they actually translate into real wins for the project, avoid them. - Glyn Williams’

最近重新复习下常用算法和数据结构,下边是看该书大致记的笔记和代码,纯手敲,有兴趣的可以参考下,都是基于python3.5 class实现,所以也算是复习了一下OOP。虽然思想都是通用的,但是使用的语言也会影响到我们的思维,我会结合一下使用python的经验来稍微分析下各种数据结构和其操作的复杂度,以便灵活选用。实现一个数据结构后最好写一些单元测试用例,否则没人知道你写的究竟对不对。坑爹的是本书有很多代码错误甚至实现错误,调试花了我很多时间。同时你还会发现很多坑爹的网络算法教程文章代码直接拷贝根本不能用,没有单元测试证明算法正确性的都是扯淡。

flask项目单元测试实践

Test early. Test often. Test automatically. Tests that run with every build are much more effective than test plans that sit on a shelf.

最近开始做公司内部项目,CRM系统(客户关系管理), 用的flask+python3.5.2。我以前闲着没事逛逛github的时候发现了这个cookiecutter-flask,就是用来生成一个项目模板的东西,直接帮你生成项目总体框架还有README文件,还是比较方便的,直接填写逻辑即可。以前并没有使用flask的经验,这次也是边摸索一边使用(好在没碰到坑),主要想记录下关于单元测试的东西。crm主要是crud操作,这次我比较重视测试代码编写,web项目单元测试需要处理数据库交互,模拟请求,模拟登录,表单提交等操作,如何编写易于构建和执行的单元测试也是需要注意的地方。新项目统一用flask+python3.5.2(python3库的支持比我想象中快,目前使用的依赖中都支持python3),前端使用vue,前后分离,后端使用flask-restful写接口。贴出来一些代码,如果写得不合适的正好可以给我指正下:)

使用vim+tmux+zsh+autojump提升效率

Unix was not designed to stop its users from doing stupid things, as that would also stop them from doing clever things.

如果你是用mac或者linux,这些工具的配合能大幅提高工作(装逼)效率(并且在服务器上也能用),本文不打算具体介绍安装方式,请自行google,主要介绍下vim一些好用的插件,说实话,真正感觉vim好用是因为github上很多牛人写的好用的插件。(当然如果你用IDE我强烈推荐Pycharm, 其实编辑器用不好反而容易写出烂代码,还是推荐不想折腾的用PyCharm,最好用的python开发工具,pycharm+vim插件也比较爽)。无论用什么工具,首要目的都是提升开发效率。


##vim小Tips

  • 更改键盘设置映射capslock到ctrl,ctrl使用非常频繁
  • 使用ctrl+[ 或者 ctr+c 代替 Esc
  • vimrc中加入两行inoremap <c-l> <c-o>:w<cr>nnoremap <c-l> :w<cr> 保存文件,再也不用每次都使用:w了,insert和normal模式下都可以用
  • Chrome安装vimium可以在浏览器里使用vim命令浏览网页
  • 高亮当前选中单词,写代码的时候高亮选中的相同单词,方便查找引用。F3激活
    1
    2
    autocmd CursorMoved * exe exists("HlUnderCursor")?HlUnderCursor?printf('match IncSearch /\V\<%s\>/', escape(expand('<cword>'), '/\')):'match none':""
    nnoremap <silent> <F3> :exe "let HlUnderCursor=exists(\"HlUnderCursor\")?HlUnderCursor*-1+1:1"<CR>

使用docker-compose运行错误收集工具Sentry

Use exceptions for exceptional problems. Exceptions can suffer from all the readability and maintainability problems of classic spaghetti code. Reserve exceptions for exceptional things.

最近在尝试搭建错误日志收集工具Sentry,发现用docker-compose工具运行起来非常方便。 目前的项目捕捉异常比较简陋,一般代码发生异常之后,写个函数发一封邮件把异常信息附上。 一开始只是在邮件附带了异常消息,但是没有加上函数调用的参数和变量值,导致问题排查起来比较困难。 后来函数加上了个locals()返回的字典返回当前函数内部变量信息,算是方便了一点。不过最近发现了神器 Sentry, Sentry’s real-time error tracking gives you insight into production deployments and information to reproduce and fix crashes.

在ubuntu server上搭建个一个尝试了一下(也可以直接用官方提供的服务),感觉还是非常强大的,界面也比较漂亮。

python单元测试

Test your software, or your users will. “Test ruthlessly. Don’t make your users find bugs for you.”

最近看了Axb的自我修养写的关于好代码,烂代码和单元测试的一些文章,挺受启发的,结合python讲一下自己对单元测试的理解和操作。

单元测试是什么

单元测试(又称为模块测试, Unit Testing)是针对程序模块(软件设计的最小单位)来进行正确性检验的测试工作。程序单元是应用的最小可测试部件。在过程化编程中,一个单元就是单个程序、函数、过程等;对于面向对象编程,最小单元就是方法,包括基类(超类)、抽象类、或者派生类(子类)中的方法。

我不是个伟大的程序员,我只是个有着一些优秀习惯的好程序员”。 —Kent Beck

因为之前实习和工作的经历都是做新项目,对于维护老项目和阅读旧代码也没太多经验,踩了一些坑。笔者在还没有彻底了解业务的情况下就重构代码,导致延误了项目进度。so naive啊。。。。。。
最近感受最深的就是项目规范化很必要,尤其是多人协作的时候。人多了的时候,不同人的水平和代码风格差异很大,如果没有统一的规范,不同的人写的代码太个人化,有时候还有很多坏味道,导致协作和他人上手很困难,项目进度也会受到影响。
另外就是程序员需要的技能还是很多的,除了写代码实现需求,还需要能够很好地理解业务,和PM,测试,其他开发人员的沟通也很重要(甚至深刻理解业务需求比编码都难,我发现我的很多做法还没摆脱典型的学生思维,囧…)。随便记录一些东西吧:

改变自己:积极心理学入门读物推荐

While you can’t control your experiences, you can control your explanations.
(你无法控制你的经历,但你可以控制你的解释。) - 马丁.塞利格曼

最近笔者学到了一些积极心理学的东西,看了一些书,希望可以帮助一些想改变自己的人。

用docker-compose构建flask应用

灵活性被过分高估–约束才是解放。- Ruby on Rails作者汉森。

最近没事的时候折腾docker,发现用docker-compose构建个flask小应用真的是炒鸡方便。一步一步来。
系统用的是ubuntu14.04。如果没有docker的话先装docker,然后装docker-compose,这个工具是python开发的,所以可以用pip安装。