《Python基础教程》学习笔记(17-18扩展与程序打包)

17. 扩展Python

17.1 Jython和IronPython

Jython对应Java,IronPython对应C#和其他的.NET语言)。

Java类(JythonTest.java)

public class JythonTest {
    public void greeting() {
        System.out.println("Hello, world!");
    }
}

$ javac JythonTest.java

$ CLASSPATH=JythonTest.class jython

# 使用
import JythonTest
test = JythonTest()
test.greeting()

C#类(IronPythonTest.cs)

using System;
namespace FePyTest {
    public class IronPythonTest {
        public void greeting() {
            Console.WriteLine("Hello, world!");
        }
    }
}

# 编译
csc.exe /t:library IronPythonTest.cs

# 更新环境变量,然后使用
import clr
clr.AddReferenceToFile("IronPythonTest.dll")
import FePyTest
f = FePyTest.IronPythonTest()
f.greeting()

17.2 编写C语言扩展

17.2.1 SWIG

SWIG是简单包装盒接口生成器的缩写。

  • 可通过它使用C语言或C++编写扩展代码;
  • 它会自动包装那些代码,一遍能在一些高级语言中使用。

使用SWIG的过程很简单

  1. 为代码写接口文件
  2. 为了自动的产生C语言代码(包装代码)要在接口文件上运行SWIG
  3. 把原来的C语言代码和产生的包装代码一起编译来产生共享库

C语言版检测回文的函数(palindrome.c)

#include <string.h>

int is_palindrome(char *text) {
    int i, n = strlen(text);
    for (i = 0; i <= n/2; ++i) {
        if (text[i] != text[n - i - i]) return 0;
    }
    return 1;
}

Python版

def is_palindrome(text):
    n = len(text)
    for i in range(len(text)//2):
        if text[i] != text[n - i - 1]:
            return False
    return True

接口文件(palindrome.i)

%module palindrome

%{
#include <string.h>
%}

extern int is_palindrome(char *text);

运行SWIG

swig -python palindrome.i

# 产生两个新文件:palindrome_wrap.c,另一个是palindrome.py

编译、连接以及使用

# Linux
$ gcc -c palindrome.c
$ gcc -I$PYTHON_HOME -I$PYTHON_HOME/Include -c palindrome_wrap.c
$ gcc -shared palindrome.o palindrome_wrap.o -o _palindrome.so

# Mac
$ gcc -dynamic -I$PYTHON_HOME/Include/python2.5 -c palindrome.c
$ gcc -dynamic -I$PYTHON_HOME/Include/python2.5 -c palindrome_wrap.c
$ gcc -dynamiclib palindrome_wrap.o palindrome.o -o _palindrome.so -Wl, -undefined, dynamic_lookup

使用

import _palindrome

17.2.2 自己研究

应用计数

Py_INCREFPy_DECREF分别来增加和减少一个对象的引用计数。

/* 必须首先被包含 */
#include <Python.h>

static PyObject *is_palindrome(PyObject *self, PyObject *args) {
    int i, n;
    const char *text;
    int result;
    if (!PyArg_ParseTuple(args, "s", &text)) {
        return NULL;
    }
    n = strlen(text);
    result = 1;
    for (i=0; i<=n/2; ++i) {
        if (text[i] != text[n-i-1]) {
            result = 0;
            break;
        }
    }
    return Py_BuildValue("i", result);
}

/* 方法/函数的列表 */
static PyMethodDef PalindromeMethods[] = {
    /* 名称、函数、参数类型和文档字符串 */
    {"is_palindrome", is_palindrome, METH_VARARGS, "Detect palindromes"}
    /* 一个列表结束的标记: */
    {NULL, NULL, 0, NULL}
};

/* 初始化模块的函数(名称很重要) */
PyMODINIT_FUNC initpalindrome() {
    Py_InitModule("palindrome", PalindromeMethods);
}

然后编译

$ gcc -I$PYTHON_HOME -I$PYTHON_HOME/Include -shared palindrome2.c -o palindrome.so

17.3 本章的新函数

函数描述
Py_INCREF(obj)增加obj的引用计数
Py_DECREF(obj)减少obj的引用计数
PyArg_ParseTuple(args, fmt, …)提取位置参数
PyArg_ParseTupleAndKeywords(args, kws, fmt, kwlist)提取位置和关健词参数
PyBuildValue(fmt, value)通过C语言值创建PyObject

18. 程序打包

18.1 Distutils基础

简单的Distutils安装脚本(setup.py)

from distutils.core import setup

setup(name='Hello',
      version='1.0',
      description='A simple example',
      author='z',
      py_modules=['hello'])

# 确保在同一目录下存在名为hello.py的模块文件

18.2 打包

18.2.1 建立存档文件

使用sdist命令(用于 “源代码发布” )

python setup.py sdist

18.2.2 创建Windows安装程序或RPM包

python setup.py bdist --formats=wininst

18.3 编译扩展

假设已经在当前目录中放置了源文件palindrome2.c,下面的setup.py脚本可以用于编译(和安装):

from distutils.core import setup, Extension

setup(name='palindrome',
      version='1.0',
      ext_modules = [
          Extension('palindrome', ['palindrome2.c'])
      ])

如果只想在当前目录编译扩展,可以使用以下命令:

python setup.py build_ext --inplace

编译SWIG

from distutils.core import setup, Extension

setup(name='palindrome',
      version='1.0',
      ext_modules = [
          Extension('palindrome', ['palindrome.c',
                                   'palindrome.i'])
      ])

18.4 使用py2exe创建可执行程序

py2exe作为Distutils的扩展,可用来创建可执行的Windows程序。

# hello.py
print 'Hello, world!'
raw_input('Press<enter>')

# 将hello.py放入空目录,然后创建setup.py
from distutils.core import setup
import py2exe

setup(console=['hello.py'])

# 运行脚本
python setup.py py2exe

18.5 本章的新函数

函数描述
distutils.core.setup(…)用setup.py脚本中的关键字参数配置Distutils
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值