2009年10月31日土曜日

URIからパスを取得する

urlparse モジュールを使う

# -*- coding: utf-8 -*-

import urlparse
import urllib

o = urlparse.urlparse("file:///home/yoshi")
s = o.path

# 日本語が含まれている場合
s = urllib.unquote(s)

print o
print s

実行すると
ParseResult(scheme='file', netloc='', path='/home/yoshi', params='', query='', fragment='')
/home/yoshi

詳細はドキュメントで

2009年10月29日木曜日

オブジェクトのブール値を取得する

組み込み関数 bool で取得する
# -*- coding: utf-8 -*-

# 組み込み関数boolで取得できる
b = bool([])

# クラスに特殊メソッド __nonzero__ __len__
# を定義すると返す値を変更できる
# 二つとも定義すると __nonzero__ が優先される
class A:
    def __nonzero__(self):
        return False
class B:
    def __len__(self):
        return 0

b = bool(A())

b = bool(B())

詳細はドキュメントで

2009年10月27日火曜日

属性値アクセスをカスタマイズする

特殊メソッド __getattr__ __setattr__ __delattr__
をクラスに定義すると属性値アクセスをカスタマイズできる

class A:
    dic = {}
    def __getattr__(self, name):
        return self.dic[name]
    def __setattr__(self, name, value):
        self.dic[name] = value
    def __delattr__(self, name):
        del self.dic[name]

a = A()
a.x = 1
print a.x
del a.x

詳細はドキュメントで

PyGTKでウィンドウを表示する

Windowを表示する
import gtk

def win_destroy_cb(window, data=None):
    gtk.main_quit()

win = gtk.Window()
win.connect("destroy", win_destroy_cb)
win.show_all()
gtk.main()

実行すると

WindowにButtonを追加し
Buttonがクリックされたらprintするようにする
import gtk

def b_clicked_cb(button, data=None):
    print "clicked"

win = gtk.Window()
win.connect("destroy", gtk.main_quit)

b = gtk.Button("button")
b.connect("clicked", b_clicked_cb)

win.add(b)
win.show_all()

gtk.main()

実行すると

WindowにVBoxを追加し
VBoxにLabelを3つ追加する
import gtk

win = gtk.Window()
win.connect("destroy", gtk.main_quit)

vbox = gtk.VBox()
vbox.pack_start(gtk.Label("label1"))
vbox.pack_start(gtk.Label("label2"))
vbox.pack_start(gtk.Label("label3"))

win.add(vbox)
win.show_all()

gtk.main()

実行すると

2009年10月26日月曜日

C言語で書いた関数をPythonで使う

まずはC言語のプログラムを書く
/home/yoshi/python/cfunc.c
#include <Python.h>

static PyObject *cprint(PyObject *self, PyObject *args) {
    char *s;
    if(!PyArg_ParseTuple(args, "s", &s)) {
        return NULL;
    }
    printf(s, "");
    return Py_None;
}

static PyObject *add(PyObject *self, PyObject *args) {
    int i1, i2;
    if(!PyArg_ParseTuple(args, "ii", &i1, &i2)) {
        return NULL;
    }
    return Py_BuildValue("i", i1 + i2);
}

static PyObject *get_list(PyObject *self, PyObject *args) {
    PyObject *list;
    int i, n;
    if(!PyArg_ParseTuple(args, "i", &n)) {
        return NULL;
    }
    list = PyList_New(0);
    for(i = 0; i < n; i++) {
        PyList_Append(list, PyInt_FromLong(i));
    }
    return list;
}

/* メソッドテーブル */
static PyMethodDef methods[] = {
    {"cprint", cprint, METH_VARARGS, "cprint(str)"},
    {"add", add, METH_VARARGS, "int add(int, int)"},
    {"get_list", get_list, METH_VARARGS, "list get_list(int)"},
    {NULL, NULL, 0, NULL}
};

/*
初期化関数
変数名initcfuncはinitのあとに任意の名前をつける
この場合 cfunc なので initcfunc になる
*/
PyMODINIT_FUNC initcfunc(void) {
    (void) Py_InitModule("cfunc", methods);
}

cfunc.cをコンパイルするのに
Pythonのdistutilsパッケージを使いプログラムを書く
/home/yoshi/python/setup.py
from distutils.core import setup, Extension

module1 = Extension("cfunc", sources=["cfunc.c"])

setup(name='cfunc', version='1.0',
      description='This is a demo package',
      ext_modules=[module1])

ディレクトリを移動する
$ cd /home/yoshi/python
setup.pyを実行しcfunc.cをコンパイルする
$ python setup.py build

2つのファイルが生成される
1. /home/yoshi/python/build/lib.linux-i686-2.6/cfunc.so
2. /home/yoshi/python/build/temp.linux-i686-2.6/cfunc.o

cfunc.soを/home/yoshi/pythonディレクトリにコピーする

使ってみる
/home/yoshi/python/test.py
import cfunc

cfunc.cprint("hello\n")
print cfunc.add(1, 2)
print cfunc.get_list(10)

print cfunc.cprint.__doc__
print cfunc.add.__doc__
print cfunc.get_list.__doc__

実行すると
hello
3
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
cprint(str)
int add(int, int)
list get_list(int)

詳細はドキュメントで