Python装饰器兼容加括号与不加括号的写法

使用Django的时候,我发现一个很神奇的装饰器:@login_required, 这是控制一个view的权限的,比如一个视图必须登录才可以访问,可以这样用:

同时,如果要达到这样一种效果:如果用户没有登录,那么就把用户重定向到登录界面,可以这样用:

所以这个装饰器可以带括号写,又可以不带括号写。很神奇有没有。正常的接收参数的装饰器,就算没参数也应该写成@login_required()

好奇去查了一下,在stackoverflow找到一种实现,挺有意思的。先晒出答案:

使用起来很简单,只要给装饰器用@doublewrap装饰一下,这个装饰器就支持写括号和不写括号两种写法了。

原理也不难,只有短短不到10行代码。

装饰器我们都知道,是用来处理一个函数,返回一个新的函数的(如果你不理解装饰器,可以看一下这个经典的解释)。

我们使用的,就是被装饰器装饰的新函数了。装饰器只是一个语法糖,其实它也是一个函数,给它传入一个函数作为参数,就返回一个新的函数。那么既然装饰器也是一个函数,我们就可以用装饰器装饰这个函数。也就是,“装饰器的装饰器”。

装饰器第一个参数肯定是原函数,如果装饰器可以接收参数的话,要么第一个参数是原函数,后面跟别的参数;要么就只有原函数一个参数。所以,我们这个“装饰器的装饰器”做的事情就是,判断装饰器接收的参数,如果只有一个并且第一个参数是可调用的(callable),那么这就是一个无参数的装饰器(不需要加括号)。如果还有别的参数,就返回一个生成装饰器的函数(decorator_maker)。

装饰器是一个函数。装饰器被装饰过之后,这个装饰器运行之前就会先运行装饰器的装饰器的代码,也就是我们的doublewrapp。然后返回值可能是一个装饰器,也可能是一个装饰器的maker(有参数的装饰器),然后装饰器再执行,装饰原函数。

这里有点绕,因为本来装饰器里面一般就会有三四层函数了,(maker, decorator, wrapper, realfunc),再加上一个装饰器的装饰器,会有点理解困难。如果理解不了,最好不要对着网上的博文(包括本文)企图格物致知了,多去看看代码,多写一写。


2017年12月31日更新:《Python3 Cookbook》中提供了另一种实现方法,代码如下:

这种原理也比较好理解,看例子1,我们知道这等价于logged(add),第一个参数是函数,所以直接返回。看例子2,等价于logged(level=logging.CRITICAL, name='example')(spam)logged的第一个参数func是None(如果是装饰器语法,第一个参数会默认传入函数,而这里直接是函数调用,并非装饰器。所以会返回一个partial函数,这个partial函数是真正的装饰器,然后再走后面装饰器的路子。其实,这种方法也是利用了“判断传入装饰器的参数”。

参考资料

  1. How to create a Python decorator that can be used either with or without parameters?
 

推荐一个Mac上管理Service的工具:LanuchRocket

开发中,经常需要开很多服务,比如mysql,redis,任务队列等等。每种任务的启动方式又不一样,查看运行状态又需要记住很多不同的命令,就很烦。

最近从同事那里发现一个很棒的工具:LanuchRocket。这个工具可以扫描通过brew安装的service,可以方便、直观地看它们的运行状况,以及管理服务。

安装方法很简单。

安装完之后,打开设置,在最后一行就能找到LanuchRocket了。(找了好长时间都不知道从哪里启动,还以为是lanuchpad或者命令行启动,囧。)
然后可以scan brew安装的服务程序,就可以一键开关服务了。

 

VimScript学习笔记(11):List和Dictionaries

Vim中有两种可以存放元素的集合(容器),列表和字典。

List

列表(List)在Vim中是有序的,可以混合存放不同元素的集合。

List是从下标0开始索引的,-1可以表示最后一个元素,-2表示倒数第二个元素。

Vim的list支持切片操作(类似Python),包含头也包含尾。

类似Python一样,VimScript可以对String进行切片。

可以使用+连接两个list。

List的默认方法

List有很多build-in functions。

Dcitionaries

VimScript的字典(Dictionares)和Python的Dict,Ruby的hashes,JavaScript的objects很像。

字典用花括号表示,value可以是任意类型,但是key必须是strings

Vim可以处理字典最后的逗号,因此我们最好永远在字典的最后加一个逗号,尤其是在多行字典的时候,这样添加新的键值对不容易出错。

取出字典值的方式和其他的编程语言一样。如果下表不是string的话,会先转换成string

也可以使用点号。

添加新的key-value也和其他语言一样。

remove函数可以删除某个键值对,并且返回被删除的值。unlet与它的功能一样,只是没有返回值。如果试图删除一个不存在的值,会发生错误。

字典有以下build-in functions,关于功能,请阅读:help.

  1. get()
  2. has_key()
  3. items()
  4. keys()
  5. values()
 

极力推荐《巨人的陨落》和《世界的凛冬》

在亚马逊看到《世界的凛冬》的时候,感觉就像玩了一款从没玩到的好游戏之后,还没从深深地满足感中回过神来,又发现这款游戏出了一个长度相当的DLC一样。之前读《巨人的陨落》,觉得真是一部不可多得的好书,写的如此真实,引人入胜,让人不忍卒读。发现此肯·福莱特手中的此书竟然是一个系列,《巨人的陨落》只是三部中的第一部!真是又惊又喜。于是这段时间又走着坐着的着迷这部书,上周终于看完了。

看过《巨人的陨落》之后,我逢人便推荐,还有一次在招聘的时候,和一个HR谈这部分谈了一个小时。我发现,虽然之前看过《一战简史》这种书,但是还是不能详细说出来几个国家经历一战的始末。但是看完《巨人的陨落》之后,随口就能说出来某个国家一站中的阵营,作战原因,同盟,利益等等。读完之后心里久久不能平静,却一直没在博客写点什么。难以下笔啊!作者的水平实在是高,我根本无从评论这部作品,只有惊叹的份。其实我向人推荐此书的时候,心里也是战战兢兢的,生怕自己说的不好,让别人对这书的印象坏了,就不想去看了,那这对别人来说可是不小的一个损失。

世纪三部曲分别是:《巨人的陨落》,《世界的凛冬》,《永恒的边缘》。

这部书以一种奇特的方式在讲述历史。书中从小处展开,将了五个家庭的故事,见证了浩荡的历史长河。作者像讲个故事一样,让你觉得一战,罢工,革命这些东西不再是过去一个世纪的事情了。而是发生在一个家庭的事情,如果你生在了一百年之前,这就是你要经历的事情。发生了战争,你家里的青年要去打仗。政府鱼肉百姓,你要去抗争。一战爆发前夕,从书中都能感受到弥漫在欧洲的火药味。虽然你我都知道,战争已经发生了。但是读到这里的时候,心还是提到了嗓子眼。为茉黛和沃尔特祈祷,不要宣战啊。

《巨人的陨落》作为第一部,从英国的工业革命开始,到德国投降,慕尼黑啤酒馆政变为止。几乎写到了这段时间欧洲发生的所有重要的历史:十月革命,一战,无限制潜艇战,施里芬计划的破产,威尔逊对于维护世界和平的热情。除了历史,还有几个家庭平凡的故事,比如贵族和女仆之间的悲剧爱情,被大战分离的英德恋人,爱上了弟弟的怀孕女友的俄国穷苦人,把黑帮老大的女儿搞大肚子阴差阳错继承家业的司机。使这本书充满着虚构而又显示的特有的魅力。

《世界的凛冬》也丝毫不逊色于第一部。从战后德国的破败开始,讲希特勒是如何在这种环境中建立起自己的政权。接着讲德国是如何走上法西斯的道路的。以前,我总以为这段时间的德国人是自卑的,将仇恨发泄在犹太人身上。读了这本书之后,才发现其实很多德国人也是无辜的,比如社会民主党人,共产党人,他们反对独裁,为争取民主斗争。可是纳粹在政治上的表现非常粗暴,几乎是用暴力夺取了政权。然后希特勒非常具有感染力的演讲能力俘获了大多数德国人(以及德国青年)的心,让他们相信了,纳粹可以给他们一个失业率低的强大德国。

20世纪三四十年代,这几乎是民主的低谷。欧洲笼罩在法西斯的阴影中,唯一还有抵抗能力的俄国是红色布尔什维克的天下。这好像在告诉世界:民主是不行的,世界上最强大的两个力量都不是民主的。甚至书中描写到,沃洛佳对美国总统还需要像选民自己做的事的原因感到惊讶。我觉得这个时候只有美国是一个自由、民主的地方。可惜美国对日本投的原子弹毫无必要,杀死了无数无辜的平民,不然的话,美国就是我心中完美的一个国家了。

从书中可以看出,作者是反对战争,反对独裁的。几次提到:不要让我们的后代再去参加战争,要让我们的后代生活在一个自由,民主的社会中。可以说,一战和二战都是父辈错误的决定导致的后果,让后代去偿还。

书中也有很多爱情故事非常感人。我认为此书的三观极正。年轻的时候,人们都会犯很多错误,但是犯错误并不可怕,怎么对待这些错误才重要。有些错误对人的伤害是永久的,无法选择逃避,无法用钱解决,我们只好永远地背负这些错误生活着。

什么是爱情。要得到爱情不是门当户对就可以了,不是你一个人优秀就可以了,就算是两人互相喜欢,也远远不够。要收获爱情实在是太难了。

茉黛和沃尔特,是一战时候跨越两个敌对国(英国与德国)之间的爱情。没有任何通信,几年不见,要忠于对方,还要对对方有信心,太难得了。要知道,战时军官的性生活一般比较混乱。艾瑟尔·威廉姆斯,年轻时爱上根本不可能的伯爵,还怀孕了,最后也终于找到自己的另一半,生活的也蛮不错。黛西,年轻时的不成熟和虚荣对身边的比利视而不见,患难时刻才知道自己爱的是谁。获得爱情是需要代价的。

肯·福莱特笔力了得,写的故事也一点都不狗血,从哪个方面看,这都是一部好书。

但这样的著作会存在一个很明显的缺陷:从五个家庭来写五个国家,其中难免要安排这些人物不断商场,就导致巧合实在是太多了。整个世界看起来像是一家人(又怎么不是呢)。我和欣欣发明了一个游戏,随便说出书中两个人的名字,看他们两个人不认识,如果不认识,需要通过多少人来认识,也蛮有意思的。

 

记录一个pip安装错误

今天使用pip安装一个requirements.txt列表的时候,碰到一个错误:

问题是出在了“cryptograp”,网上查了一下,有人说安装一下xcode的命令行工具就好了:

但是我执行这个命令的时候,说是已经安装了。

又在另一个地方查到,使用下面这个命令安装,居然成功了。