Mac pyenv安装失败的解决办法

写了很久的Python2,今天被Python3 *等特性吸引了,忍不住想试一下。

在MAC OS X上Python的多版本共存,我们可以使用pyenv来解决,配合virtualenv,可以轻松搭建多个虚拟环境。

但是安装的时候,遇到了两个问题。

在官网的issues#429发现,用下面的方式解决。

然后又遇到了下面的问题:

然后又查到了issue#451,应该使用下面的命令来安装。

然后,就安装成功了。


如果需要使用虚拟环境,可以使用下面的命令安装pyenv-virtualenv插件,然后新建虚拟环境。

以这样的方式新建的虚拟环境,位置在~/.pyenv/versions如果使用pycharm的话,可以从这个路径导入。

 

Python对Json的解析

什么是Json

Json是一种常用的数据交换结构,由于轻量、易于阅读和编写等特点,在网络方面应用很广。

它的格式一般是这样的:

对象是一个无序的“‘名称/值’对”集合。一个对象以“{”(左括号)开始,“}”(右括号)结束。每个“名称”后跟一个“:”(冒号);“‘名称/值’ 对”之间使用“,”(逗号)分隔。

例如下面这样:

它的值可以是双引号括起来的字符串(string)、数值(number)、truefalsenull、对象(object)或者数组(array)。这些结构可以嵌套。

使用Python编码和解析Json

Python内置了json包来帮助我们完成对json的操作。

将Python的字典结构导出到json使用json.dumps(),将json读成Python的字典结构,使用json.loads()

如果不是针对string操作而是对文件操作,分别使用json.load()函数和json.dump()函数。

默认的类型对应如下:

JSON Python
object dict
array list
string unicode
number (int) int, long
number (real) float
true True
false False
null None

其他数据类型与Json之间的编码和解码

一般来说,Python对json的解析是listdict之间的操作,如果需要其他类型与json之间转换,就需要object_hook参数。先定义一个类,将类的字典初始化成json的key-value键值对。这样,json的参数就变成了类的属性。

还可以通过指定“函数”来进行转换。

用函数来指定序列化的方法,即将对象的“属性-值”对变成字典对,函数返回一个字典,然后json.dumps会格式化这个字典。

如果是通过函数将json变成对象,首先获得类名,然后通过__new__来创建一个对象(不调用初始化函数),然后将json字典的各个属性赋给对象。

使用方法如下:

参考

 

JavaScript异步执行的坑

今天被JavaScript的异步执行坑了一把。

情况是这样的,我要接入云片网的短信接口。此平台为了防止自己的客户被短信轰炸机利用,要求客户在发送验证码之前必须要求验证码验证。于是我写了个先验证验证码然后才能点击“发送短信”按钮的程序。

ifenglv-loginpage

用户输入验证码之后,点击按钮,手机收到验证码。图片验证码的输入检测是这样的:一旦焦点离开input,就发送ajax到后台验证是否正确:

然后发现问题了:如果访客在输入验证码之后直接点击“发送按钮”。那么,焦点就直接从input离开,然后触发了按钮事件,并不会触发ajax去后台验证(正常的流程应该是点击空白区域失去焦点,验证通过,然后再点击按钮)。

于是我的做法是,按钮点击之后,先验证验证码一次,然后再触发发送短信

然而,结果依然是不会验证,仿佛验证验证码的代码没有执行。我在验证码的函数中打印出调试信息,却显示的确执行了。


最后发现,原来是因为“异步执行”。

在浏览器端,耗时很长的操作都应该异步执行,避免浏览器失去响应,最好的例子就是Ajax操作。在服务器端,”异步模式”甚至是唯一的模式,因为执行环境是单线程的,如果允许同步执行所有http请求,服务器性能会急剧下降,很快就会失去响应。

所以说,ajax的代码是异步执行的。在执行“验证码函数”的时候,点击按钮事件函数依然继续执行。到快执行完的时候,ajax这边也得到服务器的回复了,通过了验证。然而按钮事件却以“验证码未通过”执行完了函数。

现在我才知道这个“异步执行”是什么意思了。函数为了不阻塞,把剩下的事情教给callback函数来做,自己继续做剩下的事情。这个“同步执行”的编程很不一样,无法控制他们先做完这个、再做这个。但是无疑这提高了浏览器的响应能力。

参考:Javascript异步编程的4种方法


170113更新:最近又被坑到了,还是要怪自己不注意啊。

开发的过程中遇到一个bug,困扰了好久,有一个日历,需要根据issue显示日历中每一天的事件,现象是有的时候显示得出来,有时候显示不出来。仔细研究了一下,发现原来有两个地方有ajax调用,两个ajax收到结果之后都会更新同一个变量,其中一次更新是对的,一次是错的。如果错的比快的慢,那么后返回的错误的结果就会覆盖正确的……,改掉就好了。

 

 

Linus Torvalds谈代码品位:重写代码,排除特例

Linus接受了Ted演讲的采访:林纳斯•托瓦兹: Linux 操作系统之父, 采访中,主持人和他谈到代码品位的问题。展示了两段代码:

第一段,没有品位的代码:

code_no_teast

第二段,有品位的代码:

code_have_teast

这是从单向链表删除元素的函数,区别在于,第一段代码要判断“要删除的元素”是不是元素的头,而第二段并没没有做这个if判断。

原因是:如果要删除的是中间元素,那么只要把上一个元素的next指针指向下下一个元素就好了;如果要删除头元素的话,第一段代码所做的是,重新建一个头,指针指向下下个元素,然后把链表的头换成新的头;而第二段代码直接将原来的头的指针指向下下个元素了。

除了没有新开辟空间,第二段代码还好在:兼顾了所有情况,也就是不存在特殊情况的判断了。

Linus说:

这一个比较好。 它没有if语句。 这完全不影响—— 你不必了解这里为什么没有“if”语句, 你需要了解的是 有时候你可以换个角度看问题, 重写代码,排除特例, 完美覆盖所有情况。 这就是好的代码。 同时也很简单。 这是最基本的原则。 其实这都不重要—— 当然,细节非常重要。

对我来说,我愿意与之共事的人, 必须有好的品位,这就是如何…… 我举的这个例子很傻, 没什么意义,因为实在太短。 好的品位体现在更长的代码里。 好的品位体现在能看清全局 甚至有一种直觉, 知道怎么把事情做漂亮。

我在写代码时,喜欢写很多if。现在看来,这样不仅并没有提高安全性(自以为自己考虑了大多数情况),而且还变得更加繁琐。以后应该注意一下。


2018年1月2日更新:

在软件设计中,有一个原则叫做“最小惊讶原则”(Principle of Least Astonishment),可以参考这篇:http://lucumr.pocoo.org/2011/7/9/python-and-pola/ 和这篇 https://akaedu.github.io/book/ch03s03.html

 

django数据库migrate失败的解决方法

Django是一个MVC架构的web框架,其中,数据库就是“Module”。使用这种框架,我们不必写一条SQL语句,就可以完成对数据库的所有操作。在之前的Django版本中,我们像操作本地对象那样操作数据对象,在更改保存之后,执行python manage.py syncdb命令来同步数据库,在我使用的1.9.2版本中,需要依次执行一下步骤:

  1. python manage.py makemigrations (这个命令会根据你对数据库做出的更改生成操作数据库的python脚本)
  2. python manage.py migrate (这个命令会执行python脚本)

我遇到的问题是,执行makemigrations没有问题,但是执行migrate的时候有问题。于是我修改了modules.py中错误的代码,再次执行,却一直出问题。提示如下:

我删掉了makemigrations生成的代码,然后重新使用makemigrations生成脚本,还是出错。

原来,这是由于出错的时候,migrate命令已经执行了部分脚本,也就是说,to_user_id属性已经被操作过了,在数据库中,已经无需再操作了,所以执行migrate命令重新更新makemigrations的脚本会出错。

解决办法

重新生成makemigrations不行,执行migrate也只会全部执行。那么我们只好把数据库恢复到出错的那次执行前面的样子。

migrations

 

恢复方法:在project/app/migrations下有每次对数据操作所生成的脚本。找到出错那次脚本,打开脚本,可读性还是很高的,将所对应的数据库更改还原(当然得使用mysql语句了)。

然后删掉这次migration,重新make 然后执行。

实在不行,还有一个万不得已的办法。几乎所有的数据库错误都可以用这个方法解决:

将migrations文件夹下的文件除了__init__.py全部删掉,然后将数据库drop掉,重新建数据库。然后make,migrate,就可以使用一个新的数据库(但愿你永远用不到这个方法)。