Enterprise Just Builder

Solution for Enterprise Software Architecture

Python

PyDAAL 简介 (1)数据结构

Intel DAAL 是在针对英特尔架构优化过构建模块上编写的, 为所有数据分析阶段提供了支持。通过 DAAL, 数据驱动决策获得了包括数据获取、预处理、转换、数据挖掘、建模和验证等等基础支撑。Python 用户可以通过称为 PyDAAL 的 Python API 获取这些基础支撑。 利用 Python 进行机器学习时,你可以通过一个简单的脚本 API 来访问 PyDAAL。此外, PyDAAL 提供了独特功能, 可以轻松地将 Python 脚本化的批处理分析扩展到在线 (流) 数据获取和/或分布式数学处理。

在本系列文章中, 我们将从最基础的部分开始,逐一介绍 PyDAAL 的基础知识。第一部分将介绍 Intel DAAL 的自定义数据结构、数值表和数据管理在 PyDAAL 世界里的表示。1

一、PyDAAL 数据管理
Intel DAAL 支持以下几种数据处理方式:

  • 批处理
  • 在线处理
  • 分布式处理
  • 复杂处理(结合在线处理和分布式处理)

本文重点关注批处理方式。在线和分布式处理将在后面的文章中进行讨论。

编程方面的一些思考
强类型:Python 脚本大量使用了动态类型 (鸭子类型) , 借助于 Python 解释器在运行时来进行类型推断。但对于内存占用敏感或进行混合代码部署的情况, 这种做法可能会导致问题。PyDAAL API 调用了用 C++ 和汇编语言编写的库, 这迫使用户使用混合代码环境。因此, PyDAAL 需要一致的类型, 其支持 numpy 类型 “np.float32”, “np.float64”, 和 “np.intc” 。静态/强类型不仅允许显式声明数据类型以实现最佳内存管理, 还可以在编译过程中强制进行类型检查, 大大缩短了运行时间。

>>> 阅读全文

 

, , ,

Python编写的强大的通用解析器

Spark 是一种用 Python 编写的强大的、通用的解析器/编译器框架。在某些方面,Spark 所提供的比 SimpleParse 或其它 Python 解析器要多得多。不过由于它完全是用 Python 编写的,所以速度也会比较慢。

我将在本文中继续介绍一些解析的基本概念,并对 Spark 模块进行了讨论。解析框架是一个内容丰富的主题,它值得多花时间去全面了解;这篇文章为读者和我自己都开了一个好头。

在日常的编程中,我经常需要标识存在于文本文档中的部件和结构,这些文档包括:日志文件、配置文件、定界的数据以及格式更自由的(但还是半结构化的)报表格式。所有这些文档都拥有它们自己的“小语言”,用于规定什么能够出现在文档内。我编写这些非正式解析任务的程序的方法总是有点象大杂烩,其中包括定制状态机、正则表达式以及上下文驱动的字符串测试。这些程序中的模式大概总是这样:“读一些文本,弄清是否可以用它来做些什么,然后可能再多读一些文本,一直尝试下去。”

解析器将文档中部件和结构的描述提炼成简明、清晰和说明性的规则,确定由什么组成文档。大多数正式的解析器都使用扩展巴科斯范式(Extended Backus-Naur Form,EBNF)上的变体来描述它们所描述的语言的“语法”。基本上,EBNF 语法对您可能在文档中找到的部件赋予名称;另外,较大的部件通常由较小的部件组成。小部件在较大的部件中出现的频率和顺序由操作符指定。

举例来说,清单 1 是 EBNF 语法 typographify.def,我们在 SimpleParse 那篇文章中见到过这个语法(其它工具运行的方式稍有不同):
  

>>> 阅读全文

 

, , , , , ,

编译Python源代码 为嵌入Python做准备

在上面几篇文章我们已经详细介绍如何在 C/C++ 程序中嵌入 Python 解释器,或者是利用 C/C++ 来扩展 Python 的功能。如果你从网上下载 Python 的 MSI 安装包中的类库和 Dll 文件来运行例子,很有可能你会遇到 access violation 异常,导致宿主程序崩溃。这是因为宿主程序和 Python 的 Dll 文件依赖于不同的 C 语言运行时。

为了提高应用的稳定性,建议应该采用目标编译器从头编译 Python 源代码。本文将详细介绍如何用 VC++ 8.0 和 VC++ 10.0 从头编译 Python 源代码,这里选用的是最新的 Python 2.7.2 版本。(Python 3.x 版本因为与 Python 2.X 版本语法不兼容,而未曾普遍使用)

Python 的标准库内置了许多功能, 如要完整的编译, 需要下载一些第三方的开源程序:

Python 2.7.2 对各软件的版本在 Python-2.7.2\PC\VS8.0\pyproject.props 中有定义,如果需要不同的版本,只需要修改pypoject.props 里的版本号即可,不过注意,高版本的软件包未必兼容于 Python 2.7.2。

这些源文件下载后需要解压到和 Python 2.7.2 同层的目录, 如下图所示,并需将文件夹的名字改为和图中一致:

>>> 阅读全文

 

,

在多线程C/C++应用中使用嵌入式Python

文章评价:
脚本语言是快速编写富有弹性的代码的重要方法之一,在 Unix 系统自动化管理中已经应用了多种脚本语言。现在,在许多应用开发中,也提供了脚本层,这大大方便用户实现通用任务自动处理或者编写应用扩展,许多成功的应用,诸如 GIMP、Emacs、MS Office、PhotoShop、AutoCAD 等都应用了脚本技术。在某种意义上,一切皆可脚本化。

在另一篇文章中,我们已经介绍了如何在 C 应用中嵌入 Python 语言,通过这项技术,可以让应用的高级用户来修改或定制化他们的程序,你可以充分利用 Python 的语言能力而不用自己去实现嵌入语言。Python 是一个不错的的选择,因为它提供了干净直观的 C 语言 API。关于如何在 C 应用中嵌入 Python 解释器,你可以参考:让 Python 成为嵌入式语言一文。

现在我们来更深入地探讨一些问题。 鉴于许多复杂的应用都会利用多线程技术,本文将着重介绍如何创建线程安全的界面来调用 Python 解释器。

这里的所有例子都是用 Python 2.7.2,所有的 Python 函数都以 extern “C” 定义,因此对于 C 和 C++,其使用是别无二致的。

Python C 和线程
在C程序中创建执行线程是很简单的。在 Linux 中,通常的做法是使用 POSIX 线程(pthread) API 并调用 pthread_create 函数。关于如何使用 pthreads,你可以参考 Felix Garcia 和Javier Fernandez 著的 “POSIX Thread Libraries”一文。为了支持多线程, Python 使用了互斥使访问内部数据结构串行化。这种互斥即 “全局解释器锁 – global interpreter lock”,当某个线程想使用 Python 的 C API 的时候,它必须获得全局解释器锁,这避免了会导致解析器状态崩溃的竞争条件(race condition)。

>>> 阅读全文

 

, ,

利用C语言扩展Python模块

文章评价:
Pyton 和 C 分别有着各自的优缺点,用 Python 开发程序速度快,可靠性高,并且有许多现成模块可供使用,但执行速度相对较 慢;C 语言则正好相反,其执行速度快,但开发效率低。为了充分利用两种语言各自的优点,比较好的做法是用 Python 开发整个软件框架,而用 C 语言实现其关键模块。本文介绍如何利用 C 语言来扩展 Python 的功能,并辅以具体的实例讲述如何编写Python的扩展模块。

与其它普通脚本语言有所不同,程序员可以借助 Python 语言提供的 API,使用 C 或者 C++ 来对 Python 进行功能性扩展,从而即可以利用 Python 方便灵活的语法和功能,又可以获得与 C 或者 C++ 几乎相同的执行性能。执行速度慢是几乎所有脚本语言都具有的共性,也是倍受人们指责的一个重要因素,Python 则通过与 C 语言的有机结合巧妙地解决了这一问题,从而使脚本语言的应用范围得到了很大扩展。

在用 Python 开发实际软件系统时,很多时候都需要使用 C/C++ 来对 Python 进行扩展。最常见的情况是目前已经存在一个用 C 编写的库,需要在 Python 语言中使用该库的某些功能,此时就可以借助 Python 提供的扩展功能来实现。此外,由于 Python 从本质上讲还是一种脚本语言,某些功能用 Python 实现可能很难满足实际软件系统对执行效率的要求,此时也可以借助 Python 提供的扩展功能,将这些关键代码段用 C 或者 C++ 实现,从而提 供程序的执行性能。

本文主要介绍 Python 提供的 C 语言扩展接口,以及如何使用这些接口和 C/C++ 语言来对 Python 进行功能性扩展,并辅以具体的实例讲述如何实现 Python 的功能扩展。

Python 的 C 语言接口

>>> 阅读全文

 

,

让Python成为嵌入式语言

文章评价:
C 和 C++ 这两种强大的语言可以创建高性能本地编译代码,其缺点也比较明显,即运行时的灵活性差。一旦 C/C++ 应用编译完成,代码基本是静态的,有时这会成为大问题。例如,如果想要通过创建插件来扩展应用的功能,就不得不处理复杂的动态链接问题,这一个大麻烦。而且还要求用户必须对 C/C++ 有所了解,这大大限制了编写应用扩展的人群。

更好的方法是用某种脚本语言来扩展应用。使用脚本语言,你可以获得更多运行时的灵活性,同时缩短开发时间,降低开发扩展的学习曲线。不幸的是,创建一种脚本语言是个艰巨的任何甚至本身就可能成为一个大问题。不过,我们可以利用现成的脚本语言。比如 Python,你可以将解释器直接嵌入在应用中,无需在应用中添加太多代码就能获得 Python 的强大功能和灵活性。

在应用中使用Python
在程序包含 Python 解释器是相当简单的。Ptyhon 提供了单一的头文件Python.h,包括了在应用中嵌入解释器的所有定义。其中包含很多内容,包括一些标准头文件。为了高效地编译,如果仅包括你用到的那部分接口固然不错,不过 Python 并未提供这个选项。如果你看过Python.h,你可以看到它定义了多个重要的宏,包括相当数量的公用头文件,这些都是文件后续的独立组件所需要的。

要将应用和 Python 解释器链接在一起,你需要运行python-config程序来获得链接选项,并将之传递给编译器。在我的系统上,参数是

-lpython27 -lm -L/usr/local/python27/libs

一个非常简单的嵌入应用

>>> 阅读全文

 

,