Pegasus' Blog
保持一颗好奇心

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

python项目免坑指南

我不是个伟大的程序员,我只是个有着一些优秀习惯的好程序员”。 —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安装。

ubuntu常用工具和python虚拟环境安装脚本

Make it easy to reuse. If it’s easy to reuse, people will. Create an environment that supports reuse.

经常装ubuntu的环境,每次都要重新把vim,tmux等工具安装上,最近整理了一下安装脚本。地址在这个https://github.com/PegasusWang/linux_config。包含了tmux,vim,docker,zsh等开发常用的工具,vim为python做了配置,包含了各种常用功能。

python web入门一年(附python web入坑指南)

Invest regularly in your knowledge portfolio. Make learning a habit.

从大四实习到现在,做python web相关的东西也一年左右了,从一个毫无web基础的菜鸟成为一个仅仅算是入门的python工程师。上周拿到了木瓜移动的offer,入职之前写一下自己的经历帮助希望想要入门python web的同学吧,同时也希望国内的python圈可以发展更好,有更多喜欢python的同学能加入到python程序员的世界里。


why python?

都说牛逼的程序员是不能按照语言来分的,但是没办法,作为菜鸟的我有语言洁癖。自从我在大三暑假实习(做C++测试)的时候接触了python,就再也不想写别的语言了。写c++再写python,让我感觉就像学了汇编之后再学c,估计用了c之后再也不想写汇编了。于是买了一本《python核心编程》我的python学习之路就开始了。

python用requests+tor搭建轮换ip爬虫

一般防爬虫有很多办法,最基本的是判断header是不是浏览器,比如python有个robot-detection库可以判断,不过这个太好模拟了,没有用。然后可以通过分析日志限定用户ip一定时间段内访问次数,或者通过cookie、session限定特定用户的访问次数等。理论上说,凡可以看到的内容都是可以通过技术手段爬到的,只是难易的差别。
下面记录一下在ubuntu server上用tor搭建一个轮换IP的代理,如果爬虫一定时间段内没有得到内容,就可以换一个IP了。你可以先参考最后的几个链接大致了解下。系统用的vultr日本机房ubuntu server14.04。这是一种不用花钱的解决方案,也可以直接购买一些提供IP代理的服务,不需要自己折腾了。(注意:国内的服务器提供商使用的ISP可能限制了tor,如果你按照下边方法发现总是ttl超时,看下tor的log。推荐用国外的服务器跑爬虫)

python缓存模块的一些用法

Caches are bugs waiting to happen.- Rob Pike.

最近接触了几个关于python缓存模块的一些用法,记录一下。


python3.2的@functools.lru_cache

functools 模块在python3.2以后新加入了这个装饰器,用来缓存一些耗时的IO请求结果或者周期调用的函数结果,如果缓存数据超出maxsize的值,就是用LRU(最近最少使用算法)清除一些缓存结果。
官方文档给出了几个示例:

tornado写博客碰到的一些问题

最近还是打算继续写个博客练手,不过为了增加一些难度,需要自己实现登录、注册、权限管理、后台管理等功能。tornado不像django那样什么都给了, 也不像flask那样丰富的插件支持,不过也有一些github项目可以作为参考。慢慢记录一下实现过程中碰到的一些小问题。博客采用tornado、mongodb(motorengine) redis(session模块)等实现,参考了http://codingpy.com 的代码,这个网站叫做编程派,用flask写的,我看源码里头用到了一些flask插件,不得不说 flask这种插件扩展真滴很强大,很方便。

Understanding The Python GIL

虽然面试被拒,不过每次与牛人的交流都是一次很好地学习。我发现很多东西还是模棱两可,要不就是知其然,不知其所以然。写代码的时候很多东西都是临时上网查查,然后拿来用,慢慢就成了api工程师,还是没法成为真正的程序员。
比如GIL这个东西,从来没有深究过,只是知道cpython的实现有个GIL,只知道python解释器为每个执行的线程上锁,导致每次只能够执行一个线程。但是为什么需要GIL?( This lock is necessary mainly because CPython’s memory management is not thread-safe.)
线程切换发生了什么?为什么python不移除这个软肋?这些从来没有仔细想过。网上搜集了一些资源,分享一下吧:

python用装饰器实现多线程

Tomorrow.py

无意中发现github上这么个库tomorrow.py, Magic decorator syntax for asynchronous code in Python 2.7,使用装饰器就可以实现多线程,看起来很神奇。示例如下:

获取拉勾指定地区职位的小脚本

最近公司没啥事了,想跳槽了,不过处境比较尴尬,刚出来混几个月,技术又很一般,有点难找。
感觉拉勾网在互联网行业招聘方面做的不错,不过目测地区招聘没有具体筛选到哪个区域,比如只有北京市的,却没法精确到海淀区的。还是想在学校附近找个工作吧,就写了个脚本筛出来所有在海淀区的python岗位,思路比较简单,查询请求,然后遍历列表页面拿到所有的职位id号,再 请求所有这些id的职位页面,每个页面可以得到位置信息,抠出来地理位置符合要求就输出这个url。

还是先上以前写过的一个异步小爬虫,网页多的时候速度比较快。async_spider.py

Python如何用协程模拟线程,tornado爬虫示例

Python如何用协程模拟线程
之前贴过一个tornado改写的爬虫示例脚本之家全站文章爬虫,可能有些python初学者看得有点头晕。其实笔者学python也不久,协程一直没太能理解,从tornado示例改写成这个爬虫类的时候碰到了很多问题,最不能理解的就是为什么那个异步爬虫可以模拟出并发来。这次又重新回顾了一下,加深了理解。下边就解释一下。之所以使用异步爬虫而不是多线程爬虫,是因为线程开销比较大,开多了线程会导致切换变慢,而且一般线程占用资源也比较多,虽然多线程处理IO密集型任务还是可以提升很多效率的,但是处理网络请求的时候还是倾向于用异步机制。

搞了一个python内容聚合小站点"Python之家"

最近不忙,就搞了一个python的学习站点,包括文章、文档、书籍、新闻等资料。名字叫做python之家,域名是http://pyhome.org/,欢迎来访。博客系统直接使用的nodejs开发的ghost,文章书籍等来自网络和订阅号收集,还有自己写的一些文章。欢迎对python感兴趣的程序员一起维护和协作,您也可以直接投稿,文章均使用协议署名-非商业性使用-相同方式共享 3.0 中国大陆 (CC BY-NC-SA 3.0 CN)发布。

用python写一个命令行有道词典

平常都是用终端敲, 有时候不会的词语也懒得打开词典了,干脆搞了个简单的查词命令.思路也很简单,直接调用有道的api,解析下返回的json就ok了。只用到了python原生的库,支持python2和python3.

Mac Install Python3.5

安装

python3带来了很多新特性,甩掉了历史包袱,增加了对异步的支持,先建立环境学习下~~~
使用brew安装,再使用virtualenv建立python3.5的环境,这样不会和自带的环境冲突。
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
没有brew先使用上面的ruby命令安装。

1
2
3
4
5
$ brew update
$ brew install pyenv
$ pyenv install 3.5.0
$ pyenv install 2.7.10
$ pyenv versions

ubuntu+nginx+supervisor部署tornado

记录一下最近部署tornado的过程:

安装所需软件

使用apt-get安装nginx,redis,supervisor等需要用到的服务。
使用pip命令安装项目需要的python依赖。


修改文件描述符数量

默认ubuntu每个进程最多打开1024个文件描述符,有时候会提示”Too many open files”的错误,需要先修改这个限制。

  1. sudo vi /etc/security/limits.conf
    在文件尾加上
1
2
* hard nofile 65535
* soft nofile 65535
  1. sudo vi /etc/pam.d/su
    将pam_limits.so这一行注释删除.

  2. sudo vi /etc/profile
    最后加上ulimit -SHn 65535
    重启后用ulimit -n查看应该已经是65535.