python开智书

程序执行过程

一个简单例子

打开http://www.codeskulptor.org,在里面粘贴下面7行代码:

import simplegui    
def draw(canvas):  
    canvas.draw_text("Good job!", [50,112], 48, "Red")
frame = simplegui.create_frame("Home", 300, 200)    
frame.set_draw_handler(draw)  
frame.start()
print 'Welcome'  

可以看到程序执行过程:
命令行输出:Welcome
画布上画出:Good job!

在这简单的几行程序里,究竟发生了些什么?
首先定义了一个叫draw的函数,能够在画布上画点什么。 创建了一个frame,启动起来。
调用了print这个系统函数,在控制台打印出了‘Welcome’。

你明确的调用了print! 誰调用的draw? 你仅仅把draw这个函数传入到一个叫做frame的对象里面去了,这是你做的事. 那究竟谁调用了draw?

关于函数调用(call)与回调(callback)

什么是调用(call)?
你去便利店买东西,你是服务的使用者,便利店是服务的提供者,你调用了便利店。
容易理解的程序执行流程,都是线性的执行流程,你明确的调用一组函数,完成了某一功能。

那谁调用了draw?什么时候调用的?
做个实验,在draw函数里面加入打印时间。 你会看到,draw每秒被调用60次!也就是我们日常说的刷新频率是60帧。 看起来,draw是时间驱动的!

事实上,在程序执行的过程中,即有顺序调用的结构,也有其它的结构: 比如时间驱动的,每个时间点的到来可以理解为发生了时间事件; 比如I/O驱动的,你的程序收到了一条来自网络的消息。

这个时候,调用顺序是从系统端过来的,与正常的函数调用顺序相反, 所以叫做回调(callback)!

系统时间驱动frame内部去不停的调用draw,就是回调的过程,而draw函数本身被称作回调函数。

回调函数

看看维基百科的描述:

当程序跑起来时,一般情况下,应用程序(application program)会时常通过API调用库里所预先备好的函数。但是有些库函数(library function)却要求应用先传给它一个函数,好在合适的时候调用,以完成目标任务。这个被传入的、后又被调用的函数就称为回调函数(callback function)。

在这短短的7行代码里,融入了两种最重要的程序执行流程:顺序执行和事件驱动。
平常你使用各种软件的时候,你是在调用软件的功能;而软件的界面程序也被时间的驱动着不停的在调用自己的draw方法,画出自己。 否则,它就从屏幕消失了... 很多没有界面的程序就是这样隐匿在后台运行。

程序启动

那么问题来了,平常我们调用一个python程序,是在shell中这样调的: python test.py 那这个属于调用还是回调?

shell也是一个程序,接受了你敲入的参数。派生出一个进程,运行test.py。 从宏观上说,我们调用了shell, shell 回调了test.py中的main函数(python中无缩进的代码)。test.py本质上就是一个回调函数。

所以,编程就是为操作系统提供服务扩展,你的程序供操作系统回调。 你开始编程,你就不仅仅是个软件消费者,而是服务提供者。

你正在创造价值。

附录:

http://chengyichao.info/learnable-programming/

  • 《易学编程》中作者提到,关于学习我有两个想法:
  • 编程是一种思维方式,而非机械的技能。了解 for 循环并不等于学编程, 就好比了解铅笔不等于学画画。
  • 人能理解他所看到的东西。 如果程序员看不到程序在做什么,就能不理解程序。

  • 因此编程系统的目标应该是:

  • 让程序员有效地思考,并鼓励他们这么做
  • 让程序员看到程序的执行过程,并理解这个过程

关于python的模块调用原理 http://stackoverflow.com/questions/419163/what-does-if-name-main-do

模仿游戏,图灵 爆裂鼓手,大妈是否对我们太好了!