2008年11月29日

什么是 Python 语言

Python 语言是一种计算机编程语言,作用类似于 c/c++/java/perl/VB/Delphi 等等计算机编程语言,据有非常清晰易读的语法特点,并且是一种高级面向对象的语言,用途非常广泛,并且可以进行扩展。Python 可以运行在 Windows,Linux,FreeBSD,Solaris等等几乎所有的电脑中,也可以运行在手机中,支持 Java 和 .Net 技术。 Python(派森)语言是一种面向对象的用途非常广泛的编程语言,具有非常清晰的语法特点,适用于多种操作系统,可以在Windows和Unix这样的系统中运行。目前在国际上非常流行,正在得到越来越多的应用。Python可以完成许多任务,功能非常强大。Python核心网站是: http://www.python.org/ ,其中你可以找到很多资料。如果您第一次使用 Python, 可以下载一个试试。

Python 语言使用方便,不需要进行复杂的编译,用途非常广泛,可以进行各种软件的开发,比如: 网站,图形界面(GUI), 网络编程,数据库编程,图形图像处理,科学计算,手机编程等等。

使用 Python 最多的应该是 Google 公司了,就是人们到处都可以看到的 Google 搜索引擎。微软公司也已经开始提供Python语言的软件了。 全球著名的手机厂商 Nokia 公司早已经开始提供基于Python语言的手机开发软件了。另外,还有很多游戏是用Python开发的。另外一个比较有名的就是 Zope 公司了。

目前,Python已经有成百上千的公共资源可以供你调用。

“Python”这个英文单词的发音似“派森”,因此中文可以称之为派森。

举个小例子:

Toggle line numbers
   1 # -*- coding: utf-8 -*-
   2 # 这里是注释
   3 import string # 引用模块
   4 
   5 class abc: # 定义类
   6     def my(self): # 定义方法
   7         hi = '你好,世界'
   8         return hi
   9 
  10 def hello(int): # 定义函数或子程序
  11     """说明"""
  12     if int < 0:   # 判断
  13         res = '请输入整数'
  14     else:
  15         my_class = abc()
  16         res = my_class.my()
  17     return res
  18 
  19 print hello(2) # 调用函数 hello

下载和安装

  • 请到 Python.org下载, 当前最新的版本是 2.4.2

基础教程

Python语言是一种非常容易学习的语言,具有非常清晰的语法结构。因此,在非常短的时间内,就可以编写出实用的程序。最好先看看Python自带的文档。然后,可以再参考以下内容:

Zope 专题

Zope 是一种用途广泛的Web应用服务器软件,主要是基于Python开发的,有很多软件是构建在Zope基础上的,比如:Plone 等等。它的主页是 www.zope.org

面向对象编程

Python语言是一种有面向对象的语言,因此不仅适合于小型项目的开发, 还适合大中型项目的开发。

数据库

Python 在数据库方面也很优秀,可以和多种数据库进行连接,进行数据处理,从商业型的数据库到开放源码的数据库都提供支持。例如: Oracle, Ms SQL Server等等。有多种接口可以与数据库进行连接,至少包括ODBC。有许多公司采用着以Python为核心的架构。因此,掌握了Python使你可以充分利用面向对象的特点,在数据库处理方面如虎添翼。

Windows编程

Python 不仅可以在Unix类型的操作系统上应用,同样可以在Windows系统里有很好的表现。通过添加 PythonWin 模块,就可以通过 COM形式调用和建立各种资源,包括调用注册表、ActiveX控件以及各种COM等工作,最常见的例子就是通过程序对Office文档进行处理,自动生成文档和图表。

通过Python,你还可以利用py2exe模块生成exe应用程序。还有许多其他的日常维护和管理工作也可以交给 Python来做,从而减少维护的工作量。利用Python,你还可以开发出象VB,VC,Delphi那样的GUI程序,但却可以在多个平台上执行。这在许多方面并不逊色于Java。

多媒体

利用Python,你可以处理图象、声音、视频、动画等,从而为你的程序添加亮丽的光彩。动态图表的生成、统计分析图表都可以通过Python来完成。另外,还有OpenGL。利用PyOpenGL模块,你可以非常迅速的编写出三维场景。

  • Alice : 一个用Python和Java开发的动画编辑器。
  • VPython : 三维场景设计
  • PyOpenGl
  • PIL图像库 : 图像分析与处理模块
  • PyMol :开放源代码的分子模型系统,至少可以用于医学新药物的探索。精彩

高性能计算

Python可以广泛的在高性能计算领域发挥独特的角色,这包括科学计算领域、网格(Grid)计算领域等等。有许多模块可以帮助你在计算巨型数组、矢量分析、神经网络等方面高效率完成工作。尤其是在教育科研方面,可以发挥出独特的优势。

网络编程

Python可以非常方便的完成网络编程的工作,提供了众多的解决方案和模块,可以非常方便的定制出自己的服务器软件,无论是c/s,还是b/s模式,都有很好的解决方法。

XML

Python对XML的支持同样非常强大,有多个扩展模块可以帮助你建立、分析和处理XML,对于将来的发展趋势而言,这是非常重要的。Python支持PRC,SOAP等等。

图形界面(GUI)

Python可以非常方便的实现GUI编程,通过PyGTK,wxPython, PyQT等等模块,你就可以根据需要编写出强大的跨平台的用户界面程序。免费推荐使用PyGTK或wxPython。

关于如何用Python进行GUI开发,还可以参考 onlamp.com 的 这个页面

开发环境与编辑器

Python程序的开发工具比较多,目前主要的工具既有IDLE,PythonWin这样的免费工具, 也有一些商业性的工具。通过这些工具 ,可以让你更为快速的完成工作。

  • 集成开发环境(IDE): 列表
    • IDLE:这是Python里边自带的,基本上可以满足一般开发需要。
    • Eric3 : 非常专业的的IDE
    • SPE : 一个不错的编辑软件
    • PythonWin:这是基于Windows平台的编辑开发环境,基本上可以满足一般开发需要。下载
  • 代码编辑器:
    • LEO :完全由Python编写的程序代码编写辅助工具,可运行在多种操作系统中,支持独特的程序代码管理方式。
    • Vim :相当专业的代码编辑器,可运行在多种操作系统中,支持Python扩展。
    • Emacs:Unix系统中常用的工具。
    • SciTE:简单易用的代码编辑器,支持unicode编辑等等多种功能。
    • Quanta: 主要用于编辑网页等等

嵌入和扩展

Python 可以嵌入到其它应用程序中,也可以通过C/C++编写扩展模块,从而可以提高程序的运行速度或者完成只有通过C/C++才能完成的工作。现在Python 已经可以和C#相结合,并且结合到Visual Studio里边,实现微软的.Net思想。如果你会C语言,再学习Python,这将是一个非常棒的一种选择。以下是几个比较常用的扩展工具

如果你掌握了Python,想在Java里应用它,你可以采用Jython。Jython是采用Java语言实现的Python。这样,你只要按照 Python的语法,就可以调用Java的各种类库,快速的编写出基于Java的程序。也就是通过Jython,编写Java程序。这样就可以更为快速的实现Java的功能。另外,Oreilly已经出版了Jython方面的专著《Jython Essentials》,发展迅速。Python在面向对象方面和Java是相通的。神奇的Python!!

另外,你可以参考:

游戏编程

Python在很早的时候就是一种游戏编程的辅助工具。在《星球大战》中扮演了重要的角色。目前,通过Python完全可以编写出非常棒的游戏程序。另外,你可以到 pygame.org下载一些例子看看,确实可以让你感觉一新。

"Python plays a key role in our production pipeline. Without it a project the size of Star Wars: Episode II would have been very difficult to pull off. From crowd rendering to batch processing to compositing, Python binds all things together," said Tommy Burnette, Senior Technical Director, Industrial Light & Magic.

中文编程与文字处理

最新的 2.4 版本加强了对中文的支持,建议大家下载最新的版本。

另外,Glace对Python2.1.1进行了深入的改造,形成了一种中蟒语言,实现了可以用中文编程,详细请见: 中蟒

Python 对文字的处理功能强大,支持 unicode 和 正则表达式。下面是一些小工具,可以帮助用来排版:

  • Docutils :方便编写标准的文档
  • Epydoc :生成代码类文档
  • txt2tags :用纯文本帮助编写多种格式的文档, 和 Docutils 类似。
  • AsciiDoc

相关书籍:

手机移动

Python 也可以在手机中运行,目前,Nokia已经开始提供 Series 60 系统中的Python,通过它就可以调用手机中的各种功能啦!

成功案例与应用

目前,Python已经成功的实现企业级应用,在全球,已经有很多公司采用Python进行企业级软件的开发和应用,比如:ERP和CRM这样的应用。同时,通过Python技术,成功的实现了许多政务应用。 最有名的可能就要算 Google 啦。请查看以下一些网址:

"Python has been an important part of Google since the beginning, and remains so as the system grows and evolves. Today dozens of Google engineers use Python, and we're looking for more people with skills in this language." said Peter Norvig, director of search quality at Google, Inc.

书籍文档

目前,已经出版了多种中文书籍,不妨找一本看看。比如:

  • 《Python 核心编程》
  • 《Python 编程金典》

综合应用

以下是一些进行综合应用的软件:

  • PyMol :开放源代码的分子模型系统,至少可以用于医学新药物的探索。精彩!
  • Chandler : Lotus Notes的开发者进行的新的协同交流系统。
  • Plone :基于Zope开发的网站框架,轻松建立易于维护和管理的网站交流系统。
  • MailMan : 元老级别的邮件列表交流软件。
  • BitTorrent : BT 超强的下载工具
  • EarthClock : 挺好看的钟表
  • GNU Enterprise: 企业ERP
  • TinyERP: 小型的ERP系统

精选链接

英文:

中文:

发表于 2008-11-29 07:50 lostpencil 阅读(198) | 评论 (0)编辑 收藏

2008年11月14日

== 基于本地的Python应用程序 ==


=== 写在之前 ===
{{{
这篇所说的是关于建立python调用Flash的本地应用,不同于Adobe的Apollo。

没有用到浏览器嵌入flash网页的方法,直接在pythonwin或者wxpython建立的窗口中插入Flash ocx。

因为是操作Activex控件的方式因此大概只适用于windows平台。抱歉我并未在其它平台上试过这种方法,不过linux中应该也有类似的技术。}}}

=== Flash ocx介绍 ===
{{{
Flash ocx实际上是一种COM组件开发模型(Microsoft Component Object Model),它原先是从Windows 3.x中的OLE发展过来的。现在又被改名叫做Activex。Activex是COM的一种,一般是指带有UI界面的COM。

Flash ocx的本名是叫Shockwave Flash Object,是一个Activex控件。Activex控件文件名的后缀是ocx。

原先的Shockwave包括了很多东西。被Adobe收购的MicroMedia公司的另一个产品Director的web应用就叫shockwave,它集合了视频流、Flash、shockwave 3D于一身。

对于Director我还是挺有感情的,只不过Director到了8.5以后的版本就基本不再发展了,我也渐渐不用它了。(听说Adobe收购MicroMedia以后,还会推出Director 11)}}}


=== Flash ocx与外界通迅的方法 ===

==== 调用ocx标准COM接口IDispatch ====

这种方法最简单,也比较通用。

它又叫COM对象的自动化接口。使用自动化,对象就可以提供一个简单的自动化接口,这样脚本语言作者只需掌握IDispatch和几个COM应用程序接口就可以了。

pythonwin的作者 Mark Hammond 的一本书(Python Programming on Win32)就讲到了怎样用python直接操作COM对象(操作的函义包括使用和发布)。如果想深入细节的话,可以参考这本书。

Python 程序使用 win32com.client.Dispatch() 方法来创建 COM objects。
如创建一个 Flash COM object.

{{{#!python
>>> import win32com.client
>>> fl = win32com.client.Dispatch("ShockwaveFlash.ShockwaveFlash.9") #Flash 9 的ProgID是ShockwaveFlash.ShockwaveFlash.9,有很多工具可以查到机器内部注册的COM组件信息
}}}
这样就得到了Flash COM object,你可以让它LoadMovie,让它Play,但是你暂时还看不到它,你得传给它一个窗口,这样它才能显示在窗口。
所幸wxpython帮我们封装了这一切,你只需要调用wx.lib.flashwin.FlashWindow类就行了。

例:
{{{#!python
import wx
from wx.lib.flashwin import FlashWindow

class CGui(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, 101, "map", size = (800, 600), style = wx.FRAME_SHAPED)
self.flash = FlashWindow(self, style=wx.SUNKEN_BORDER, size = (800, 600)) #用wx.lib.flashwin.FlashWindow创建窗口
self.flash.LoadMovie(0, 'C:\\drop_shadow_dog.swf') #播放"C:\\drop_shadow_dog.swf"的Flash影片
self.flash.SetSize((800, 600));

def getText(self):
returnValue = self.flash.GetVariable('FlashValue') #从Flash端
return returnValue

def setText(self, text):
self.flash.SetVariable("PythonValue", text) #传给Flash变量

}}}
这些传递变量在Flash AS端都处于_root层级下。

这儿有个例子
http://www.sephiroth.it/weblog/archives/2004/05
/wxpython_and_flash_first_test.php
{{{#!python
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import wx, sys, os
import string, codecsfrom wx.lib.flashwin
import FlashWindow
from wx.lib.flashwin import EVT_FSCommand
#----------------------------------------
class TestPanel(wx.Panel):
def __init__(self, parent, base, swf):
wx.Panel.__init__(self, parent, -1)
self.base = base
sizer = wx.BoxSizer(wx.VERTICAL)
self.flash = FlashWindow(self, style=wx.SUNKEN_BORDER)
dlg = wx.MessageDialog(self, "This will work only under Windows!","Warning!",wx.OK | wx.ICON_INFORMATION)
dlg.Center()
dlg.ShowModal()
wx.BeginBusyCursor()
try:
self.flash.LoadMovie(0, swf)
except:
wx.MessageDialog(self, "could not load the swf file","Error",wx.OK | wx.ICON_ERROR).ShowModal()
sys.exit(2)
wx.EndBusyCursor()
self.flash.Stop()
self.flash.SetSize((self.flash.GetSize()[0],self.flash.GetSize()[1]))
# sizer
sizer.Add(self.flash, 1, wx.EXPAND)
self.SetSizer(sizer)
self.SetAutoLayout(True)
sizer.Fit(self)
sizer.SetSizeHints(self)
self.SetFlashOptions()
self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy)
self.Bind(EVT_FSCommand, self.CallMethod) ##将Flash ocx的消息事件绑定到CallMethod函数上。

def SetFlashOptions(self):
self.flash.menu = False
self.flash._set_FlashVars("data=Server started on " + sys.platform)
self.flash.Play()

def OnDestroy(self, evt):
if self.flash:
self.flash.Cleanup()
self.flash = None

# Called from Flash FSCommand
def CallMethod(self, evt):
try:
arguments = string.split(evt.args,"###")
filename = arguments[0]
body = arguments[1]
if filename == "" or body == "":
wx.MessageDialog(self, "Please check data inserted", "An Error occurred", wx.OK | wx.ICON_INFORMATION).ShowModal()
else:
dlg = wx.FileDialog(self, "Save as..." , os.getcwd(), filename, "*.*", wx.SAVE | wx.OVERWRITE_PROMPT )
if dlg.ShowModal() == wx.ID_OK:
try:
f = codecs.open(os.path.normpath(dlg.GetPath()), "w", "utf-8", "ignore")
f.write(codecs.utf_8_decode(codecs.BOM_UTF8)[0])
f.write(body)
f.close()
self.flash._set_FlashVars("data=Succesfully saved text file")
except:
wx.MessageDialog(self, "%s %s %s" % sys.exc_info(), "An Error occurred", wx.OK | wx.ICON_ERROR).ShowModal()
self.flash._set_FlashVars("data=%s %s %s" % sys.exc_info())
except:
wx.MessageDialog(self, "Please check data inserted","An Error occurred",wx.OK | wx.ICON_INFORMATION).ShowModal()
self.flash._set_FlashVars("data=%s %s %s" % sys.exc_info())

#-------------------------------------------
if __name__ == '__main__':
class TestFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1, "ActiveX -- Flash", size=(640, 480), style=wx.DEFAULT_FRAME_STYLE )
base = os.path.normpath(os.path.abspath(os.path.dirname(sys.argv[0])))
swf = os.path.normpath(os.path.join(base, "movie.swf"))
self.tp = TestPanel(self, base, swf)
app = wx.PySimpleApp()
frame = TestFrame()
frame.Center()
frame.Show(True)
app.MainLoop()
}}}

Flash端很简单,两句话就搞定了。
{{{
on (click) {
fscommand("saveFile", this._parent.fnome.text + "###" + this._parent.ftesto.text)
}}}}

这里用到了Flash的fscommand。

在Flash端点击了以后,它就会发送一个fscommand消息事件。

python端接收到了以后,由CallMethod处理。

==== 使用Flash ExternalInterface ====

ExternalInterface 类是一个子系统,通过它可以轻松地实现从 ActionScript 和 Flash Player 到 HTML 页中的 JavaScript 或任何包含 Flash Player 实例的台式机应用程序的通信。
ExternalInterface 可以提供以下功能:
{{{
■ 可以调用注册过的 python 函数。 从python端也可以调用注册过的Flash ActionScript函数。
■ 可以传递任意数量的、具有任意名称的参数;而不是仅限于传递一个命令和一个字符串参数。
■ 可以传递各种数据类型(例如 Boolean 、Number 和 String);不再仅限于 String 参数。
■ 可以接收调用值,该值将立即返回到 ActionScript(作为进行的调用的返回值)。}}}

Flash利用ExternalInterface与Python之间的通信使用特定的XML格式对函数调用和值进行编码。Flash端自动处理XML格式,Python则需要将接收到的XML数据解析和发送前打包成XML格式。

使用ExternalInterface与Python进行通信时,Flash以特定的XML格式向应用程序发送消息(函数调用和返回值),并要求来自Python的函数调用和返回值使用相同的 XML格式。

下面的 XML 片断说明了一个 XML 格式的函数调用示例:

{{{


... (individual argument values)

}}}

通过XML格式,ExternalInterface与Python之间可以传递多种类型的参数,包括Python的list和dic类型。

我们可以建立一个数据转换类来专门将翻译Python与Flash之间的通迅。

{{{#!python
class EIDataSerializer:
__xmlData=None
def __packNumber(self,p,x):
p.appendChild(self.__xmlData.createElement('number')).appendChild(self.__xmlData.createTextNode(str(x)))
return
def __packString(self,p,x):
p.appendChild(self.__xmlData.createElement('string')).appendChild(self.__xmlData.createTextNode(x))
return
def __packNone(self,p):
p.appendChild(self.__xmlData.createElement('null'))
return
def __packBool(self,p,x):
if x:
p.appendChild(self.__xmlData.createElement('true'))
else:
p.appendChild(self.__xmlData.createElement('false'))
return
def __packDict(self,p,x):
p=p.appendChild(self.__xmlData.createElement('object'))
for k,v in x.items():
n=p.appendChild(self.__xmlData.createElement('property'))
n.setAttribute('id',str(k))
self.__packData(n,v)
return
def __packList(self,p,x):
p=p.appendChild(self.__xmlData.createElement('array'))
i=0
for v in x:
n=p.appendChild(self.__xmlData.createElement('property'))
n.setAttribute('id',str(i))
self.__packData(n,v)
i+=1
return
def __packData(self,p,x): ##将Python的类型打包成XML
t=type(x)
if t in (int,long,float):
self.__packNumber(p,x)
elif t in (str,unicode):
self.__packString(p,x)
elif x==None:
self.__packNone(p)
elif t==bool:
self.__packBool(p,x)
elif t in (list,tuple):
self.__packList(p,x)
elif t==dict:
self.__packDict(p,x)
return
def __unpackNumber(self,p):
try:
return int(p.firstChild.nodeValue)
except ValueError:
try:
return float(p.firstChild.nodeValue)
except ValueError:
return None
def __unpackString(self,p):
return p.firstChild.nodeValue
def __unpackTrue(self):
return True
def __unpackFalse(self):
return False
def __unpackNull(self):
return None
def __unpackUndefined(self):
return None
def __unpackObject(self,p):
d={}
for n in p.childNodes:
d[n.getAttribute('id')]=self.__unpackData(n.firstChild)
return d
def __unpackArray(self,p):
a=[]
for n in p.childNodes:
a.append(self.__unpackData(n.firstChild))
return a
def __unpackData(self,p): ##将Flash传过来的XML解析成Python类型数值
t=p.nodeName
if t=='number':
return self.__unpackNumber(p)
elif t=='string':
return self.__unpackString(p)
elif t=='true':
return self.__unpackTrue()
elif t=='false':
return self.__unpackFalse()
elif t=='null':
return self.__unpackNull()
elif t=='undefined':
return self.__unpackUndefined()
elif t=='object':
return self.__unpackObject(p)
elif t=='array':
return self.__unpackArray(p)
def serializeReturn(self,v):
self.__xmlData=minidom.Document()
p=self.__xmlData
self.__packData(p,v)
return self.__xmlData.toxml()
def serializeCall(self,name,args):
self.__xmlData=minidom.Document()
p=self.__xmlData.appendChild(self.__xmlData.createElement('invoke'))
p.setAttribute('name',name)
p.setAttribute('returntype','xml')
p=p.appendChild(self.__xmlData.createElement('arguments'))
for v in args:
self.__packData(p,v)
s=self.__xmlData.documentElement.toxml()
return s
def deserializeReturn(self,s):
self.__xmlData=minidom.parseString(s)
p=self.__xmlData.documentElement
return self.__unpackData(p)
def deserializeCall(self,s):
self.__xmlData=minidom.parseString(s)
p=self.__xmlData.documentElement#invoke
name=p.getAttribute('name')
args=[]
p=p.firstChild#arguments
for n in p.childNodes:
args.append(self.__unpackData(n))
return (name,args)}}}


===== 从Python调用Flash函数 =====

从Python端调用Flash端函数实际上是Python调用Shockwave Flash ActiveX控件的CallFunction()方法,通过ExternalInterface从Flash调用ActionScript函数。

以下示范了从Python调用Flash函数的用法:

Python端:

{{{#!python
def CallFlash(name,args): ## name是Flash ActionScript的函数名,args是传给Flash ActionScript的参数
ds = EIDataSerializer()
s = ds.serializeCall(name,args) ## 将传递的内容打包成XML
s = flashWnd.ocx.CallFunction(s) ## 调用Shockwave Flash ActiveX控件的CallFunction()方法
s = s.encode('utf-8') ## 从ActionScript返回的任何值都被编码为XML格式字符串,并作为CallFunction()调用的返回值发送回来。
return ds.deserializeReturn(s) ## 返回值解包}}}


Flash端:

要从Python调用ActionScript函数,必须向ExternalInterface类注册函数,然后再用Shockwave Flash ActiveX控件的CallFunction()方法调用它。

Python只能调用ExternalInterface类注册函数中的ActionScript代码,而不能调用任何其它ActionScript代码。

向ExternalInterface类注册ActionScript函数的方法,如下所示:

{{{
function callMe(name:String):String
{
return "busy signal";
}
ExternalInterface.addCallback("myFunction", callMe);}}}

ExternalInterface.addCallback()方法采用两个参数。第一个参数为 String 类型的函数名,这是告诉Python端调用的函数名。第二个参数为Flash端实际ActionScript函数。

由于这些名称是截然不同的,因此可以指定将由Python使用的函数名与实际的ActionScript函数具有不同的名称。这在函数名未知的情况下特别有用,例如:指定了匿名函数或需要在运行时确定要调用的函数。

===== 从Flash调用Python函数 =====

从Flash调用Python函数实际上是Shockwave Flash ActiveX控件发送了一个控件消息FlashCall,并附带包含有关函数调用信息的XML 格式的字符串。Python将其解析成函数名和参数,并调用相应函数。

我们继续从消息流程上解析这个过程,首先Flash端示例:

{{{
public function sendMessage(message:String):void
{
ExternalInterface.call("newMessage", message); //调用了Python端的newMessage的方法,message是newMessage方法的参数
}}}}

Python端示例:

先建立一个供Flash调用的函数

{{{#!python
def newMessage(self, message):
print message
return message}}}

建立一个函数字典库

{{{#!python
def RegisterCallback(self,name,callback): ##将需要调用的函数注册
if callable(callback):
self.__callbackReg[name]=callback ##和Flash类似,name是Flash端调用的函数名。callback为Python端实际函数。
return True
else:
return False}}}

{{{#!python
self.RegisterCallback("newMessage", newMessage) ##将其注册到__callbackReg中}}}

最后接收Flash消息,处理函数调用

{{{#!python
def OnFlashCall(self, receiveString): ##注册的Activex消息处理函数
receiveString = receiveString.encode('utf-8') ##从Flash控件消息接收的XML字符串
name,args = self.__szr.deserializeCall(receiveString) ##解析成Python函数名和参数
r = self.__callbackReg[name](*args) ##函数字典中注册的函数名
ds = EIDataSerializer()
s = ds.serializeReturn(r) ##返回值打包成XML
self.SetReturnValue(s)
return}}}

这样就可在Flash端调用Python函数了。



以上方法在pythonwin和wxPython中均可使用。

发表于 2008-11-14 16:45 lostpencil 阅读(407) | 评论 (5)编辑 收藏

2008年10月18日

目前国内的聊天机器人大多都只是做了一个自然语言结构分析,然后就在此基础上做了场景记录。这2方面的努力结果最终产生了一个庞大的数据库,于是表现出来机器人的智能面不够灵活,而且速度很慢。

目前我发现人类的语言交流并不完全是的知识,信息的交流,策略占了很大比重,智能机器人语言方面的改善感觉应该加入策略的因素。

这里可以简单加入情绪因素进去,然后就是根据情绪来分类策略,这将直接导致数据库横向发展,查询效率提高很多。

而且很多策略是可以完全通过自然语言结构分析来确定句子的答复的,策略丰富化,机器人将更加智能。

目前我这方面针对朋友开发的一个机器人做了改进以后,运行速度大约提高了40%左右,至于语言效果由于策略的规划和实现还不完善,不如以前,但是大多数情况差别不大。

因为一些商业因素,就不继续说了,呵呵

发表于 2008-10-18 00:32 lostpencil 阅读(518) | 评论 (1)编辑 收藏

2008年9月28日

一个偶尔的机会接触到了MDP,马尔可夫决策过程,突然发现多年的困惑有点头绪了,分享一段东西。

以下东西摘自某博士论文部分(若有版权问题请及时告知):

以哲学观点来看,人类来到世间至少有三件事要做:认识世界;改造世界;享受世界。

在这其中,学习类问题对应认识世界,而决策类问题便是和改造世界紧密相关的。决策问题伴随着人们的日常生活,大至公司乃至国家的战略性决定,小至个人利益相关的一些选择。‘决策’又区别于简单的‘决定’以及‘选择’。它通常涉及的是一个过程,其最终对应的行动的执行一般是多步的。在每一步,都要去做一个选择。不同的选择,不同的行动,导致不同的结果,进而也意味着不同的收益。决策不能孤立的进行,若不考虑现在与将来的联系,很难在整个过程中获得最好的收益,就如同在一次长跑比赛中,我们不能在起点就用尽全力冲刺一样。事实上,决策问题与人们的社会生活的联系是如此密切,可以说,一切社会实践活动都离不开决策,甚至,从辨证的观点看,若是把主观世界也当作客观世界的一部份,那么学习本身也是一个改造世界的过程,其过程也一样讲究策略,我们改造就是自己罢了。

对于智能体而言,当其面对客观世界中存在的一个待解决的问题时,首先,他的学习能力使其在主观世界中获得了对该问题的一个抽象的描述,对应为问题的模型,这其中通常包括:

¨        问题所有可能的状态,

¨        问题发展过程的演变规律,

¨        智能体在过程中可以做出的选择,

¨        智能体所期望的结果等。

事实上,这就是MDP模型的基本构成部分,

而所谓的智能体进行决策,也就是指智能体在此模型的基础上,基于问题过程的规律进行规划,利用智能体可行的选择参与改变过程,使其朝自身期望的结果发展,最终解决问题。总的来说,决策基于问题的模型再结合规划的方法两部分完成。在人工智能领域,马尔可夫决策过程是用来建模规划问题的一个基本理论模型。以其为基础,进一步发展出一系列更具一般性的决策模型,如部分可观察马尔可夫决策过程,分布式马尔可夫决策过程,部分可观察的随机博弈及半马尔可夫决策过程等等。

 

决策总是与一个过程相联系的(当然,从广义上来看,过程可以只有一步)。智能体要在过程中做出合适的选择,将过程的发展引入对自身有利的方向,必然需要了解描述过程发展变化的知识。相对于穷举所有变化,如果某些知识,不止一次可被用来推断过程发展,即为规律。主体更需要就是这种精简的知识。

马尔可夫过程正是具有一类普遍共性的过程。这类共性既是马尔可夫性,也称无后效性。由俄罗斯数学家马尔可夫于1907提出。所谓无后效性,指的是这样一种性质:某阶段的状态一旦确定,则此后过程的演变不再受此前各状态的影响。也就是说,未来与过去无关,当前的状态是此前历史的一个完整总结,此前的历史只能通过当前的状态去影响过程未来的演变。具体地说,如果一个问题被划分各个阶段之后,阶段 I 中的状态只能通过状态转移方程去影响阶段 I+1 中的状态的得来,与其他状态没有关系,特别是与未发生的状态没有关系,这就是无后效性。从更本质的的角度来理论,可以认为马尔可夫性来源于对因果性和时间的连续性以及单向性的认可。

马尔可夫性用来描述过程的规律类似数学中使用递推公式描述数列一样,并且特点是递推式只用到了前面一项。做为区别,比如著名的斐波拉契(Fibonacci)数列,11235……的递推公式F(n)=F(n-1)+F(n-2)就用到了前面的两项。假设我们构造一个过程,逐次去读取数列中的每一项,任何一个时刻的状态便是读取到的数字。那么,斐波拉契数列对应的便不是一个马尔可夫过程。描述规律的方式很多,把握“当前的状态是此前历史的一个完整总结”这一要点后,很多过程可以被转化描述为马尔可夫过程。当然,前提是,可以做到当前状态完整总结历史这点。但事实上完美总是相对而言的,从后面不确定性的讨论也可以看到。从这个角度来说,马尔可夫过程是一个很实用的理论。在马尔可夫过程上做决策的好处显而易见,我们可以忽略历史的影响,也无需再去不断的保存历史信息,一切规划都只要从当前状态出发即可。它所蕴含的思想是将智能体有限的规划能力引导至更有价值的方向。

马尔可夫决策过程与马尔可夫过程的本质区别就是多了主体即决策者的介入。下面将依次简单介绍马尔可夫决策过程(Markov Decision Processes, MDP),部分可观察马尔可夫决策过程(Partially Observable Markov Decision Processes, POMDP),分布式部分马尔可夫决策过程(Decentralized-POMDP, DEC-POMDP),部分可观察的随机博弈(Partially Observable Stochastic Games, POSG)及半马尔可夫决策过程(Semi-MDP)之间的区别与联系。

50年代R.贝尔曼研究动态规划时和L.S.沙普利研究随机对策时已出现马尔可夫决策过程的基本思想。R.A.霍华德(1960)D.布莱克韦尔(1962)等人的研究工作奠定了马尔可夫决策过程的理论基础。1965年,布莱克韦尔关于一般状态空间的研究和E.B.丁金关于非时齐(非时间平稳性)的研究,推动了这一理论的发展。1960年以来,马尔可夫决策过程理论得到迅速发展,应用领域不断扩大。凡是以马尔可夫过程作为数学模型的问题,只要能引入决策和效用结构,均可应用这种理论。

在人工智能领域中,对决策类问题的求解过程也可以称为规划。经典规划一般基于确定式的环境模式,如搜索算法A*等。这类方法在现实应用中有很大的局限性。面对现实中的规划问题,主体对环境特性的把握常常是不完整的,正是由于这种知识的缺失,造成了不确定性。马尔可夫决策模型则可以处理这类问题。利用下图信息集合划分的方式,可以更清晰的理解不确定性,以及马尔可夫决策过程(MDP)与下面将提到部分可观察马尔可夫决策过程(POMDP)的区别。

针对某个决策问题,从信息或者知识的角度我们区分出如下所示3个依次为包含关系的集合:


1.1 决策问题中的信息划分


A
集合:为客观存在的影响过程的全部信息,是整个客观世界的世界状态中与问题所对应过程相关的因素。

B集合:为影响智能体主观决策的信息,进一步解释,是智能体主观上知道存在,并能够把握运用的一些信息。因为对于某些因素,即便智能体知道应该与过程相关,但无法把握运用,这些信息也不会影响智能体决策。比如,一般都认为掷硬币,正反面的概率各50%。事实上,风力,掷硬币的具体操作方式,抛出轨迹,用力情况,地面情况等都会影响过程结果,而这些因素通常无法把握运用,即使考虑进来,也难以改变决策。因此,这类智能体知道存在却无法把握利用的信息,及主观上根本不知道其存在而客观上却影响过程的因素,构成了B集合与A集合的差别。同时,也正是这些差别,造成了不确定性的存在。从另一个角度,只要B不是空集,基于应用的需求,就存在进行决策的意义。但对不确定性仍需进行刻画,于是便引入了统计意义上概率。

C集合:为智能体总是能观察到的信息。现实中很多决策过程,对于B集合中的信息,智能体有时观察不到。比如踢足球,自己身后球员的位置是会影响决策的,但却可能会观察不到。

根据定义内容,首先有前提A>=B>=C,进而可以对问题做下面的分类:

1> A=B=C时是一个确定性问题。

2> A>=B=C时是一个MDP问题。

3> A>=B>C时是一个POMDP问题。

MDP本身既可以处理确定性问题,也可处理不确定性问题。而POMDPMDP模型上进行了一定扩展,引入了对观察不确定性的处理。从一定意义上也可以认为,MDPPOMDP的一种极端的情况,即决策相关信息全部可观察。

MDPPOMDP模型中都认为决策的智能体只有一个,并把其它一切因素都归于客观环境。这些因素一部分是确定性的知识;另一部分则是已归入统计概率的不确定性,认为在当前条件下,从处理问题的实际情况出发,不适合再进行探究,只作概率推理。当一个过程中,有多个智能体同时决策合作来解决一个问题时,上述模型是否适用的关键因素即其他智能体的策略是否已知。策略是决策的结果,指出在过程某个状态要采用哪个行动。如果认为其他智能体策略已知,无论是确定性的策略亦或含概率表示的不确定性策略,那么其他智能体一样可以归入环境,仍可使用MDPPOMDP模型处理。否则,其它智能体会采用何种策略也是需要纳入考虑的,在生成智能体自身决策的同时,也要生成其他智能体的决策,这是其客观过程本身的模型决定的。分布式马尔可夫决策过程(DEC-MDP)及分布式部分可观察马尔可夫决策过程(DEC-POMDP)可以处理这类多智能体合作问题。

在现实应用中,多智能体间除了合作也可能存在对抗,这类问题可以归为博弈。其中本质的区别即智能体间收益评价的不同。合作类问题,各个智能体有相同的收益评价,或者说有共同的目标;而博弈类问题,各个智能体收益评价存在区别,甚至完全对立。部分可观察的随机博弈(POSG)便是进一步扩展的一个决策模型,可以处理这类带有不确定性的博弈问题。

半马尔可夫过程又可以称为非时齐马尔可夫过程,这是相对于一般的时齐马尔可夫过程而言的。所谓时齐是指过程的每两个相邻状态点间的时间间隔是一致的,对应决策过程则是每步行动的执行时间是定长的。非时齐则是描述了一类更一般的情况,对应决策过程中行动的执行时间并不固定,甚至是时间上的一个概率分布。

我的收获:早些年研究的东西,基本思路是有一定的科学理论依据的,只是出发点有了问题,所以难逃计算量的恐怖。就像目前的彩票研究者一样,最终的常理的结论是预知性不明朗,靠运气吧。现在想想其实换一个研究层面去研究,然后按原来的方法计算,很多层面的东西还是相当有可能的。感谢数学,感谢马尔可夫。

发表于 2008-09-28 01:19 lostpencil 阅读(630) | 评论 (1)编辑 收藏

2008年9月24日

我的电脑系统是XP, C盘是ntfs格式的,然后D盘是fat32格式的,这样DOS窗口里面怎么也cd 不进D盘去。
有没有什么办法,不重装系统或者格式化D盘,就可以轻松的CD D:\进去啊
因为之前D盘装了很多东西,格式化了太麻烦了

修改:
2008-09-25 08:13 by OneZ
进入D盘,只要在CMD窗口下输入D:,就可以了。前面不需要CD。

发表于 2008-09-24 23:27 lostpencil 阅读(640) | 评论 (6)编辑 收藏

起因:通过MingW和qt-win-opensource-4.4.2-mingw.exe在windows下安装QT开源版的情况,在运行QT-demos时候会发现mediaplayer那个程序launch不起来,原因是本身那个程序就没有编译成可执行文件。然后自己找到那个模块后,qmake ,make,结果发现老有错误“Cannot find -lphonon”. 网上一搜同样的问题很多,答案比较少,超级复杂,还是有点乱说的成份在。包括那些英文网站上也没有有效的解决方案。

关于phonon:
Phonon是一个跨平台多媒体编程开发平台,可使具有不同编程经验的编程人员更便捷地将多媒体功能移植到他们的应用程序中去。
Phonon起初由KDE团队开发,是发布的KDE 4.0的一个组成部分。目前,奇趣科技将Phonon进行了扩展,使其可用于如Windows和 Mac OS X在内的所有主流桌面操作系统上。此外,奇趣科技已将该源程序代码编入KDE的源代码库中,并将其采用LGPL授权。
编程人员利用Phonon,可以更方便地将多媒体回放功能运用到C++应用程序中,很多操作程序仅利用极少的几个代码便可以实现。Phonon的源代码,包括仅在UNIX 和Linux平台上使用的、基于Xine的单一后端。而奇趣科技为Linux的GStreamer创建了其它的后端实施工具,同时为Windows和Mac OS X操作系统也创建了新的后端工具。
奇趣科技把Phonon纳入公司发布的Qt 4.4之中,目前该版本已在2008年第一季度末正式发布。

办法:会出现这个问题可能是qt-win-opensource-4.4.2-mingw.exe制作者的疏忽,把Phonon模块以及相关的程序没有编译到,
解决办法其