search
LoginSignup
3
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

posted at

updated at

Pythonに組み込み関数「メガンテ」を追加する

この記事はダイジェスト版です。
技術的に詳細な内容は Pythonに組み込み関数「メガンテ」を追加する - narupoのブログ からどうぞ。

組み込み関数メガンテを追加する

こんにちは、narupoです。

Pythonも長く使っていると、見慣れた組み込み関数ばかりで飽きてしまうものです。
そこで新しい組み込み関数「メガンテ」をPythonに加えてみることにしました。

このメガンテ関数をPythonに加えれば日々のプログラミングがさらにエキサイティングになるかもしれません。

メガンテとは?

メガンテ」とは日本のRPG「ドラゴン・クエスト」シリーズで使われる呪文のひとつです。
この呪文を唱えた者は自爆し、周りを破壊して息絶えます

CPythonをゲットする

PythonにはCPythonJythonなど色々な実装がありますが、今回改造するのは最もポピュラーと思われるCPythonの実装です。

Gitを使ってCPythonのプロジェクトをクローンします。

$ git clone https://github.com/python/cpython.git

あとはconfigureとやってmakeしてPythonをビルドします。
環境はWindows10のWSLを使っています。Ubuntu16.04ですね。なので生成されるPythonがpython.exeになってます。

$ cd cpython
$ ./configure
$ make
$ python.exe

CPythonを改造する

メガンテ関数を追加するにあたって、既存の組み込み関数であるprintを参考にしたいと思います。
組み込み関数printPython\bltinmodule.cbuiltin_print関数として定義されています。

static PyObject *
builtin_print(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
{
    ...
}

この関数は同ファイル内のbuiltin_methodsに登録されています。
builtin_methodsPyMethodDef型の配列です。

static PyMethodDef builtin_methods[] = {
    ...
    {"print",           (PyCFunction)(void(*)(void))builtin_print,      METH_FASTCALL | METH_KEYWORDS, print_doc},
    ...
};

メガンテ関数を定義する

Python\bltinmodule.c内にメガンテ関数を↓のように定義します。

static PyObject *
builtin_megante(PyObject *self, PyObject *arg)
{
    const char *msg = PyUnicode_AsUTF8(arg);
    if (!msg) {
        Py_RETURN_NONE;
    }

    fflush(stdout);
    fprintf(stderr, "%s\n", msg);
    fprintf(stderr, "自爆しました。\n");
    fflush(stderr);
    exit(1);

    Py_RETURN_NONE;
}

内容的には引数のメッセージを標準エラーに出力して、「自爆しました。」と出力します。
その後、プログラムを強制終了します。

このメガンテ関数のドキュメントも定義しておきましょう。

PyDoc_STRVAR(megante_doc,
"megante(message)\n\
メガンテ(message)\n\
\n\
messageを叫んでから自爆します。\n\
プログラムは強制終了されます。");

最後にbuiltin_methodsにメガンテ関数とmegante_docを↓のように登録します。
日本語の「メガンテ」でも呼び出せるようにしています。

static PyMethodDef builtin_methods[] = {
    ...
    {"megante",          (PyCFunction)(void(*)(void))builtin_megante, METH_O, megante_doc},
    {"メガンテ",           (PyCFunction)(void(*)(void))builtin_megante, METH_O, megante_doc},
    ...
};

動作風景

組み込み関数「メガンテ」の動作風景です。

1.gif

おわりに

Pythonではけっこう簡単に組み込み関数を追加することが出来ました。
しかし、この組み込み関数メガンテ、あまり使いどころがありません

皆さんもこれを機会にPythonにオリジナルの組み込み関数を加えて、周りの人をびっくりさせてみてはいかがでしょうか。

以上、narupoでした。

関連記事

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
3
Help us understand the problem. What are the problem?