daemonfreaks.com

pythonでimport文で指定したクラスを動的生成したい

posted by jun-g at 火, 03 4月 2007 02:16 JST

ここんとこずーっと悩んでて解決方法がわからんのでブログで晒してみる。

pythonでMochiKit.DOMのcreateDOMみたいのがあったら便利かなと思って下記のようなクラスを書いた。

class Tag:
    """A base class of HTML tag."""

    name = None
    inline = True
    container = False

    def __init__(self, *nodes, **attributes):
        self.nodes = nodes
        self.attributes = attributes

    def __str__(self):
        return self.serialize()

    def serialize(self):
        text = ""
        for node in self.nodes:
            if isinstance(node, Tag):
                text += node.serialize()
                if not node.inline:
                    text += "\n"
            else:
                text += node
        tag = "<" + self.name
        attrs = map("=".join, [(x[0], "\"%s\"" % (x[1])) for x in self.attributes.items()])
        if len(attrs) > 0:
            tag += " " + " ".join(attrs)
        if text == "":
            tag += " />"
            if self.container:
                tag += "\n"
        else:
            tag += ">"
            if self.container:
                tag += "\n"
            tag += text + "</" + self.name + ">"
        return tag

サニタイズとか全然してないけど、とりあえずなのであまり気にしない。こいつから各タグのサブクラスを作っておくと、

class DIV(Tag):
    name = "div"
    inline = False
    container = True

class A(Tag):
    name = "a"
    inline = True
    container = False

下記のように使える。

>>> a = A("DaemonFreaks.com", href="http://www.daemonfreaks.com/")
>>> div = DIV("僕のサイト: " , a, style="border: 1px solid #000000;")
>>> print div
<div style="border: 1px solid #000000;">
僕のサイト: <a href="http://www.daemonfreaks.com">DaemonFreaks.com</a>
</div>

でもって、タグを全部クラスとして定義するのもアレなので、クラスを動的に生成する関数を作った。

from new import classobj
def _get_class(name, inline, container):
    name = name.lower()
    cls = classobj(name.upper(),
                   {"name": name,
                    "inline": inline,
                    "container": container})
    return cls

で、各タグの名前、inlineとcontainerの設定を用意しておけば準備完了。

# name: (inline, contaier)
TAGS = {
    "html": (False, True),
    "head": (False, True),
    "body": (False, True),
    (省略)
    "div":  (False, True),
    "span": (True, False)
    }

後は、import文が呼び出された際に、「import *」なら定義内容すべてのクラスを、タグが指定されたなら指定タグのクラスをグローバル空間に展開するようにしたい。つまり、モジュール「html」内にこれらのコードが書かれていたとして、

>>> from html import HEAD, BODY
>>> dir()
['HEAD', 'BODY']
>>> from html import *
>>> dir()
['HTML', 'HEAD', 'BODY', (省略), 'DIV', 'SPAN']

のように動作させたい。

しかし、同一モジュール内で__import__をオーバーロードしたりihookを使用してみたものの、どうも期待どおり動作しない。同一モジュール内にオーバーロードの処理を書くと、そのモジュールがimportされた後に__import__がオーバーロードされてしまう(当たり前か…)。なので、モジュール内で自分自身を再度インポートするように記述するとなんとなく上手く動いてるような感じにはなる。

importされるモジュール側でimportをhookして、指定されているクラス(orモジュール)名を取得する方法は無いものか…。

メインのPC復旧

posted by jun-g at 月, 02 4月 2007 14:09 JST

メインのPCがようやく復旧した。NOTE PCの狭い画面とはこれでオサラバ。

やったこと。865PEのマザーボードを中古で買ってきて交換。OSの入ったHDDはそのまま使用。/homeはSATA120GB*2のRAID0アレイ上に新しく構築。でもってmake worldしてからアプリも全部入れ直した。あとはバックアップHDDから必要なファイルを取り出すのみ。

あと、最近shellをbashからzshに乗り換えたので、漢のzsh(MYCOM)を参考に.zshrcを編集した。プロンプトはbashで設定していたものと同じにしたかったので、

local LIGHTGREEN=$'%{\e[1;32m%}'
local GREEN=$'%{\e[0;32m%}'
local YELLOW=$'%{\e[1;33m%}'
local BROWN=$'%{\e[0;33m%}'
local LIGHTBLUE=$'%{\e[1;34m%}'
local BLUE=$'%{\e[0;34m%}'
local WHITE=$'%{\e[1;37m%}'
local DEFAULT=$'%{\e[1;m%}'
PROMPT=$LIGHTGREEN'['$GREEN'%*'$LIGHTGREEN']'$YELLOW'['$BROWN'%~'$YELLOW']
$BLUE'%n'$WHITE'@'$LIGHTBLUE'%m'
$WHITE%(!.#.$) '$DEFAULT
setopt PROMPT_SUBST

のようにした。これは

[12:00:00][/path/to/curdir]
jun-g@hostname
$ 

のように表示される。右プロンプトは馴染めないので使わない…。後は補完とエイリアスの設定をちらほらとしてとりあえず完了。

entrycache導入

posted by jun-g at 月, 02 4月 2007 13:39 JST

PyBlosxomはファイルの更新日時がそのままエントリの投稿日時になるので、過去のエントリに追記しちゃうとそのエントリの日付が変わってしまって困るなー、って思ってたら、投稿日時を記憶するプラグインがあったことに今頃気づいた…。

ということで、ファイル名やエントリの配置などの細工なしで導入できそうなentrycacheをプラグインに追加。初回起動時に過去エントリのキャッシュを一気に作成するので、少し重かった。

あと、mod_wsgi環境ではキャッシュファイルに投稿日時が保存されなくて少しハマッた。mtimeが取得できてない?でも投稿日時の表示はできてるしなぁ。今度デバッグしてみよう。

PyBlosxom on mod_wsgi

posted by jun-g at 木, 22 3月 2007 03:36 JST

mod_wsgiのリリース間近でなんとなく盛り上がっているふうなので、僕も試してみた。

やっぱり動かすならPyBlosxomだよねぇ(Wikiにも載ってないし)という事で、Apache2.2 + PyBlosxom(svn trunk版)で動かす事に。

インストールはaodag隊長んとこに書いてあるとおり、

./configure && make && make install

で完了。当然事前にpythonとapacheがインストールされている必要あり。後はディレクトリ作ってPyBloxsomのソース一式を突っ込んでから、Apacheの設定ファイルに以下を追加した。

LoadModule wsgi_module libexec/apache22/mod_wsgi.so
(略)
WSGIScriptAlias /pyblosxom /usr/local/www/apache22/wsgi/wsgi_app.py
<Directory "/usr/local/www/apache22/wsgi">
(略)

で、あっさり動いた。素晴らしい。っていうか元々WSGI対応の作りになっているので当然そのままで動くんやけど。

Pyblosxom on Mod_Wsgi
Pyblosxom on Mod_Wsgi posted by (C)jun-g

mod_wsgiで動かすのは簡単やったけど、trunk版のPyBlosxomに新しい設定項目(locale)が追加になってて、そこに少しハマったという…。

そろそろメインのPCを復旧せねば

posted by jun-g at 火, 20 3月 2007 02:13 JST

ようやく壊れたメインPCを復旧させるべく作業開始した。

…で、まぁ色々トラブルもあったけど、とりあえずRAID0アレイ上にあった/homeのデータは全て救出できた。中古で3000円したPromiseのRAIDカードはちっとも役に立たず、新品の玄人指向の1000円のRAIDカードが役に立った。なんたる不条理。後、ヨドバシで衝動買いしたBUFFALOの250GB外付けHDDがデータの吸い出し先として役に立った。うーん、買っといて本当に良かった。

しかし依然としてB5ノート上で作業しないといけない状況には変わりないので、新しいマザーを探しにいかねば。Socket478のマザーなんて、日本橋でも探さないと見付からないかな…。E7205かi875あたりのマザーが良いんやけどな…。

という作業をしている裏で、密かにgettext祭りに巻き込まれているという…。かれこれ24時間以上ビルドしてますが何か?これが終わったら休む間も無くGNOME 2.18祭りに参加予定…。

<<  Page 113 of 127  >>