Python C/API Tutorial 3.1.1 Numbers

今日も C/API で遊んでいます. 最後の round に苦労したけど, おかげでモジュールあたりに詳しくなりました.

#include <Python.h>

void code1()
{
    PyObject *result;

    result = PyNumber_Add(PyInt_FromLong(2), PyInt_FromLong(2));
    PySys_WriteStdout(">>> 2+2\n");
    PySys_WriteStdout("%ld\n", PyInt_AsLong(result));

    // This is a comment
    PySys_WriteStdout(">>> # This is a comment\n");
    result = PyNumber_Add(PyInt_FromLong(2), PyInt_FromLong(2));
    PySys_WriteStdout("... 2+2\n");
    PySys_WriteStdout("%ld\n", PyInt_AsLong(result));

    result = PyNumber_Add(PyInt_FromLong(2), PyInt_FromLong(2)); // and a comment on the same line as code
    PySys_WriteStdout(">>> 2+2  # and a comment on the same line as code\n");
    PySys_WriteStdout("%ld\n", PyInt_AsLong(result));


    result = PyNumber_Divide(PyNumber_Subtract(PyInt_FromLong(50),
                                               PyNumber_Multiply(
                                                   PyInt_FromLong(5),
                                                   PyInt_FromLong(6))),
                             PyInt_FromLong(4));
    PySys_WriteStdout(">>> (50-5*6)/4\n");
    PySys_WriteStdout("%ld\n", PyInt_AsLong(result));

    // Integer division returns the floor:
    PySys_WriteStdout(">>> # Integer division returns the floor:\n");
    result = PyNumber_Divide(PyInt_FromLong(7), PyInt_FromLong(3));
    PySys_WriteStdout("... 7/3\n");
    PySys_WriteStdout("%ld\n", PyInt_AsLong(result));

    result = PyNumber_Divide(PyInt_FromLong(7), PyInt_FromLong(-3));
    PySys_WriteStdout(">>> 7/-3\n");
    PySys_WriteStdout("%ld\n", PyInt_AsLong(result));

    return;
}

void code2()
{
    PyObject *width = PyInt_FromLong(20);
    PySys_WriteStdout(">>> width = 20\n");

    PyObject *height = PyNumber_Multiply(PyInt_FromLong(5), PyInt_FromLong(9));
    PySys_WriteStdout(">>> height = 5*9\n");

    PyObject *result = PyNumber_Multiply(width, height);
    PySys_WriteStdout(">>> width * height\n");
    PySys_WriteStdout("%ld\n", PyInt_AsLong(result));

    return;
}

void code3()
{
    PyObject *x, *y, *z;

    x = y = z = PyInt_FromLong(0); // Zero x, y and ...

Python C/API Tutorial

http://docs.python.org/tutorial/introduction.html

Python Tutorial を C/API で書いてみるとどうなるか? という実験です. 2章までは Python そのものの紹介なので3章から. 本文とかは飛ばして, コードサンプルの C/API への翻訳に注力します. (もしかしたらそのうち文書もちゃんと書いて公開するかも.)

コンパイル

コンパイル方法は以下を参考に

こんな感じでやりました.

# ライブラリ
$ gcc -Wall -fPIC -c hello.c -I/usr/local/Cellar/python/2.7.1/include/python2.7/ -lpython2.7
$ gcc -shared -o hello.so hello.o -lpython2.7

# 実行バイナリ
$ gcc -Wall -I/usr/local/Cellar/python/2.7.1/include/python2.7/ -lpython2.7 chap3.c -o chap3

今使っている Python は homebrew でインストールしたものなので, そのヘッダファイルのあるディレクトリを -I (<-large ai) オプションで指定. ライブラリは /usr/local/lib/libpython2.7.dylib にあるので, -l (<-small el) オプションの指定だけで読めたみたい.

最初のコンパイルで PyArg_ParseTuple 云々で警告が出るけど, いったん無視.

3. Python のくだけた紹介

#include <Python.h>

int main(void)
{
    Py_Initialize();
    // this is the first comment
    PyObject *SPAM = PyInt_FromLong(1); // and this is the second comment
                                        // and now a third!
    PyObject *STRING = PyUnicode_FromString("// This is not a comment.");
    Py_Finalize();
    return 0;
}

これで作った chap3 を動かしても何も出ません. 出力ロジック書いてないから当たり前ですが.

とりあえず今日はここまで.

CPython 3.2 ソースコードリーディング 第 2 回

http://partake.in/events/752c6759-83b0-4b96-a1ee-95e220977990

先月に引き続き CPython のソースを読んでいきました. 今回もやや言語処理系寄りの話になっています. Python でそういう方面の勉強会は無いからまぁいいかな? と思いつつ, 今後の方向性についてはまだ検討中です.

俺も発表しましたが, 俺以外の人の発表も楽しく聞いていました. 言語の中心部分を深く知ること自体がやっぱり楽しいです. わくわくします. 「ソースコードリーディング」というキーワードで勉強会をやると, そういう人達が集まって濃いマニアックな話ができて嬉しいです.

それと同時に集まってきてくれている人達に何か渡せているものはあるのか? と悩み考えることも多いです.

「Hack-a-thon っぽくその場で C/API を使って何か実装する」「できるだけ速い実装をする」とかいう案ももらったので, 何か変化球を入れたいなぁとも思っています.

そういう悩みの機会になる, という意味でも良い経験を積んでいるのかな, と思います.

それでは.

Licenses