Category Archives: Python学习笔记

学习Python留下的笔记,看的书包括但不限于Dive into Python 3

当初看 Dive into Python 的时候就听过装饰器,不过知道是个语法糖,感觉上没什么用,就没仔细了解,这几天看一段代码用到了装饰器,只好再研究下吧。

为什么使用装饰器?

AstralWind 在他的博客里这么说,“装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志、性能测试、事务处理等。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。”

打个比方,我是个有怪癖的人,在调用任何函数的时候总希望先输出函数的name和doc,因为我常常反复传递函数,所以最好把这个函数的引用计数也显示下?要么把函数运行时间也显示出来吧!

如果不用装饰器,我们可能在写函数的时候把name、doc什么的都print出来,这样有些麻烦,写多少个函数就得copy多少次,利用Python万物皆对象的特性,我们不妨写个函数来做这件事情:

不过这样在调用函数的时候总得先把函数传给PrintDetail(),既不美观也不方便,那么是时候让装饰器登场了:

这里我们定义了装饰器,不过,等等,我运行完发现怎么我还没调用func,他就运行了?
上面这个装饰器是不合格的,如果你尝试去掉用的话,甚至会发现装饰器只会调用一次。
这是因为我们还没弄清楚究竟什么时装饰器,我先提供一个正确的装饰器:

为什么要提供_PrintDetail,而且还要把它返回?
为什么现在看起来就不会没调用自动运行?
为什么现在多次运行都可以自动调用装饰器了?

虽然没有读过Python关于这部分的源码,但是大概可以推测出Python涉及到装饰器时怎么工作的:
Read More →

不知道有没有人喜欢用ctypes,反正我是不大喜欢的。用了ctypes之后程序会显得很凌乱——为了调用c/c++写的dll,动不动c_int或者c_char_p,要是碰上dll里各种用结构体或者数组或者指针的话,那更是悲剧了。想象下先写个c_char_p,然后再pointer(),然后组合起来一个struct,再排出个数组,最后还要获得其指针?

简直就是个悲剧,好了,吐槽完毕,下面说正经的,有一个数据采集仪,提供一个dll方便我们取数据,VC6.0下编译的,某个函数在文档中给出原型如下:

  1. // 功能描述:获取传感器的测量值。   
  2. // 输入参数:pSensorVal,用户分配的用来保存传感器值的数组首地址;   
  3. //           pSensorCount,用户分配的数组长度;   
  4. // 输出参数:pSensorVal,保存采集到的传感器的值;   
  5. //           pSensorCount,分析仪中的传感器数,如果分析仪中的传感器数大于用户指定的个数,则只返回用户指定个数的传感器值。   
  6. // 返 回 值:成功返回1;失败返回负数;   
  7. //           -1:获取失败   
  8. FBGA_DR_API int FBGA_GetSensorVal (SSensorVal *pSensorVal, int *pSensorCount);  

Read More →

本文由Mathematrix译自由Jake Vanderplas撰写的Matplotlib Animation Tutorial

Matplotlib 1.1 版新添加了一些非常帅的用来制作动画的工具,你可以在Matplotlib的Example页看到一些非常棒的例子(OldExample, Example)。在这里我与大家分享下我使用这些工具的一些经验。

基本动画

动画工具的中心是matplotlib.animation.Animation基类,这个类提供了动画功能的基础。两个主要接口则分别是imeAnimation和FuncAnimation,你可以在这里查看API文档。下面我说说怎么使用我认为最实用的FuncAnimation。

首先我们用FuncAnimation做一个基本的动画,这个动画可以在屏幕上动态显示正弦函数的图像。

  1. “””  
  2. matplotlib animation example  
  3.  
  4. author: jake vanderplas  
  5. email: vanderplas@astro.washington.edu  
  6. website: http://jakevdp.github.com  
  7. license: bsd  
  8. please feel free to use and modify this, but keep the above information. thanks!  
  9. “””  
  10.   
  11. import numpy as np   
  12. from matplotlib import pyplot as plt   
  13. from matplotlib import animation   
  14.   
  15. # first set up the figure, the axis, and the plot element we want to animate   
  16. fig = plt.figure()   
  17. ax = plt.axes(xlim=(0, 2), ylim=(-2, 2))   
  18. line, = ax.plot([], [], lw=2)   
  19.   
  20. # initialization function: plot the background of each frame   
  21. def init():   
  22.     line.set_data([], [])   
  23.     return line,   
  24.   
  25. # animation function.  this is called sequentially   
  26. def animate(i):   
  27.     x = np.linspace(0, 2, 1000)   
  28.     y = np.sin(2 * np.pi * (x - 0.01 * i))   
  29.     line.set_data(x, y)   
  30.     return line,   
  31.   
  32. # call the animator.  blit=true means only re-draw the parts that have changed.   
  33. anim = animation.funcanimation(fig, animate, init_func=init,   
  34.                                frames=200, interval=20, blit=true)   
  35.   
  36. # save the animation as an mp4.  this requires ffmpeg or mencoder to be   
  37. # installed.  the extra_args ensure that the x264 codec is used, so that   
  38. # the video can be embedded in html5.  you may need to adjust this for   
  39. # your system: for more information, see   
  40. # http://matplotlib.sourceforge.net/api/animation_api.html   
  41. anim.save(‘basic_animation.mp4′, fps=30, extra_args=['-vcodec', 'libx264'])   
  42.   
  43. plt.show()  

 

让我们一步一步来研究这个并看看下面将会发生什么。在引入几个必须的numpy和matplotlib库后,脚本开始设置这个plot:
Read More →

本文程序在Windows7 + python2.7 + wx2.9 + pygame1.9 下调试正常通过。 这几天在给一座桥写实时监控程序(众:你丫去年不就在写这玩意儿么,怎么今年又写开了……答:去年写的是个检测,就相当于给数据做了个皮肤,今年做的是监测,连着几百号传感器呢,技术含量不能同日而语……)。出于种种目的我终于说服项目组允许我拿python写这个程序,以前就很少写GUI程序,这下自己也纯属赶鸭子上架,结果没想到还遇到了个麻烦。 是这样的,桥上有个传感器,可以感应到有车辆从桥上经过,这个传感器可以记录到这个车的车速、加速度、轴重、轴距等等信息,然后工控机1受到这些数据后会向局域网广播,我写的程序跑在工控机2上,收到数据在屏幕显示就行了,这个过程倒是不难,只要下面几句就能完成:

  1. s=socket.socket(socket.af_inet,socket.sock_dgram)   
  2. s.setsockopt(socket.sol_socket,socket.so_reuseaddr,1)   
  3. socket.setdefaulttimeout(0.5)   
  4. ip=socket.gethostbyname(socket.gethostname())   
  5. d,a=s.recvfrom(90)   
  6. s.close()  

 

因为这个数据什么时候发过来并不知道,所以应该开个线程然后while循环这句d,a=s.recvfrom(90),当收到数据就出发个事件,但是我研究好久线程间通信、事件什么的也没弄出来,只好写了个轮循,就是收到数据就放到一个大家都能访问的空列表里,在画动画的时候不断检查这个列表长度,一旦列表长度大于0就从里边取数据,取一个删一个。这样写好像比较笨,再看了“小明明s à domicile”里写的设计模式后发现这个其实符合观察者模式,与其不断查这个列表不如在收数据这里调用画动画的函数,这样来通知效果应该会好些。说起来,在Python Essential Reference里有个生产者消费者模型,记得以前看操作系统原理看过,可惜没用上。 收上数据直接显示应该就行了吧,这个本来挺简单但是项目组要求这个显示一定要用个动画来显示,具体就是来个车要能看到一个格子里面有这个车的所有信息,然后这个格子要从屏幕下方移动到屏幕上方,定住;下一个移动到这个之后,如此循环,当屏幕上攒够4个就把最上面那个移走,整体往上顶一个,再把新的移上来,大致就是怎么个效果:

Record Read More →

最近在做PythonChallenge,挺有意思的,不少都靠谷歌才有了idea,不过代码都是自己写的,记录下,免得将来忘掉。(不要直接用这里的答案来过关哦,Avoid looking for spoilers.)

p.s. 科普:PythonChallenge分0-33共34关,当你开始玩这个游戏时,网站会告诉你第一关的地址以及有关后面关卡的地址的提示,你的任务就是尽量搜集这些有关下一关的地址的线索,然后找到下一关的确切地址(通常需要编程)。听起来有点像寻宝游戏,其实却是差不多。

注:所有程序在Windows XP sp3 + Python 3.2 下调试通过哦,如果涉及到第三方包,则对其版本另作说明。

0. 0.html

话说Hint是try to change URL address,这句话既是提示,也为以后解所有问题奠定了基础。

我刚看到这个hint时,看了一眼地址:0.htm,哦,下意识的就直接把0.htm改成了1.htm虽然不是答案但也不远了——在这个页面里有个提示:2**38 is much much larger.
哦,看来确实要计算0.htm那个图片里的那个2的38次方啊,用python计算得
2**38 = 274877906944
OK,输入274877906944.htm,成功进入第一关。

1. map.html

那个图片提示很明显——凯撒密码,凯撒密码非常常见而且易被破解(特别对于长明文),以前看数论与密码,第一章讲的就是这个。

代码可像我这样用chr(ord())来写,也可以提前写个字典然后用string对象translate()函数(就像字母算术的穷举算法那样)。

代码:

  1. # -*- coding : utf-8 -*-   
  2.   
  3. text = “g fmnc wms bgblr rpylqjyrc gr zw fylb. rfyrq ufyr amknsrcpq ypc dmp. bmgle gr gl zw fylb gq glcddgagclr ylb rfyr’q ufw rfgq rcvr gq qm jmle. sqgle qrpgle.kyicrpylq() gq pcamkkclbcb. lmu ynnjw ml rfc spj.”   
  4. trans = ”   
  5.   
  6. for ch in text:   
  7.     if ord(ch) >= ord(‘a’) and ord(ch) <= ord(‘z’):   
  8.         trans = trans + (chr(ord(ch) + 2) if ord(ch) + 2 <= ord(‘z’) else chr(ord(ch) + 2 - 26))   
  9.     else:   
  10.         trans = trans + ch   
  11.   
  12. print(trans)  

 

获得的字符串是:“i hope you didnt translate it by hand. thats what computers are for. doing it in by hand is inefficient and that’s why this text is so long. using string.maketrans() is recommended. now apply on the url.”

OK,将text换成map再运行下程序获得ocr即是下一关地址。

2. ocr.html

打开这一关发现页面上没什么有用的东西,于是打开源代码看下“find rare characters in the mess below”,然后下面一大堆字符,ok,按照他所说的写一个统计字符串字符个数的程序:

  1. # -*- coding: utf-8 -*-   
  2.   
  3. strtext = ”’past by your self
  4. ”’  
  5.   
  6. dictwords = {}   
  7.   
  8. for chtemp in strtext:   
  9.     if chtemp in dictwords:   
  10.         dictwords[chtemp] += 1   
  11.     else:   
  12.         dictwords[chtemp] = 1   
  13.   
  14. print(dictwords)  

 

统计结果是:“{‘\n’: 1221, ‘!’: 6079, ‘#’: 6115, ‘%’: 6104, ‘$’: 6046, ‘&’: 6043, ‘)’: 6186, ‘(‘: 6154, ‘+’: 6066, ‘*’: 6034, ‘@’: 6157, ‘[': 6108, ']‘: 6152, ‘_’: 6112, ‘^’: 6030, ‘a’: 1, ‘e’: 1, ‘i’: 1, ‘l’: 1, ‘q’: 1, ‘u’: 1, ‘t’: 1, ‘y’: 1, ‘{‘: 6046, ‘}’: 6105}”

嗯,那就是’a’, ‘e’, ‘i’, ‘l’, ‘q’, ‘u’, ‘t’, ‘y’了。组成个单词——“equality”。
Read More →