2012年2月20日月曜日

自動テスト時にPEP8コーディング規約をチェックさせる

unittestを自動テストでまわす時に、PEP8をコーディング規約をチェックさせてます。
この手の規約を守るのは面倒くさいのですが、
Eclipse(PyDev)に特化させることで かなり効率が上がったので、紹介します。

まず、【ここ】を参考にして、PEP8チェックをunittestに組み込んでみました。

それだけだと芸が無いので、テスト結果の出力形式をPyDev用に編集しました。

PyDevは、トレースバックのログから、エラー箇所へのリンクを作りますよね?
これはログの出力結果のパターンから リンクを生成しているように思えたので、PEP8のログを整形してトレースバックログに似せてみました。
(この辺、Pythonは改造が簡単で良いですね)

すると、トレースバックのログと同様に、PEP8に違反したところへのリンクができました!
これで、PEP8違反箇所の修正が、かなり簡単になります。

以下、ソースです

2012年2月13日月曜日

成長の軌跡:PythonでSingleton実装


昔書いたコードを見直しすると、むずむずしてきて面白いですね!
Python で Singletonを実現するためのコードの変遷を書きます。


2012年2月8日水曜日

SyntaxHighlighterを入れてみました

Google先生も古い情報ばかり教えてくるので、探し出すのに結構かかったのでメモ。

設定方法:

SyntaxHighlighter を Blogger で使えるようにするには、
以下のサイトを参考に設定すると良いです。

SyntaxHighlighterのグーグルBloggerでの使い方
http://yksmtmks.blogspot.com/2011/05/syntaxhighlighterblogger.html

SyntaxHighlighter 3.0 on Blogger
http://kenmemo.blogspot.com/2011/05/syntaxhighlighter-30-on-blogger.html

 Yet Another How To Use SyntaxHighlighter in Blogger with Autoloader
http://ywafield.blogspot.com/2011/03/yet-another-how-to-use.html

この一文
SyntaxHighlighter.config.bloggerMode = true;
なくても動くみたいですが、いちおう入れてます。

使い方のメモ:




エンコードはここが便利:
www.netyasun.com/syntaxhighlighter/source-escape.html

英語の読み書きを訓練するのが一番大事な気がする今日この頃です・・・。

2012年2月7日火曜日

GoogleAppEngin(Python2.7)で、NDBによる非同期アクセスをお試し中


以下のサイトで、GAE/PのNDB(Next DB module)モジュールについて知りました。
https://sites.google.com/site/copypesouko/--manyuaru/datastore-plus-tutorial-ja
(ただ、今は【ここ】の情報が最新らしいですね)


全然ドキュメント読めていないのですが、(Python創始者のGuidoがせっせこ作っている)GAE/Pのデータストアで非同期アクセスを行う為のモジュールらしいですね。
(他にもコンテキスト処理?とかいろいろ出来るらしいけれど難しそうなので読んでません)

非同期にアクセスできるようにということは、
  • 複数のテーブルへのアクセスを並列実行できるので、反応を改善できることがある。
    (とはいえ、高価なデータストアに頻繁にアクセスする設計は間違っている気がします)
  •  書き込み結果を待たずにレスポンスを返せる。たとえば、ブログの更新のように、書き込みにほぼ成功するような更新なら、反応を早くできる。
    具体的には、データストアとMemcacheへの更新を並行して実施することで、データストアへの書き込みを待たずにキャッシュを使って更新結果を参照させることができる。
といったような効果を期待できますね!

ただ、この新しいモジュールではkey_nameを使えません(!)


from google.appengine.ext.ndb.model import (Model as _NdbModel,
                                            transactional)


class Model(NdbModel):
    u"""google.appengine.ext.db.Modelの動きを真似るラッピング
        ぶっちゃけ、こんなラッピングはしないほうが良いと思います
    """

    def __init__(self, **kwds):
        _kwds = kwds.copy()
        key_name = _kwds.get('key_name')
        if key_name != None:
            _kwds['id'] = key_name
            del(_kwds['key_name'])
        NdbModel.__init__(self, **_kwds)

    @classmethod
    def get_by_key_name(cls, key_name, **kwds):
        return cls.get_by_id(id=key_name, parent=kwds.get('parent'))

    @classmethod
    @transactional
    def insert_or_fail(cls, id_or_keyname, **kwds):
        u"""挿入して挿入された値を返します。
            キー重複は、何もせずにNullを返します。全然非同期じゃないし、動作未検証です。
        """
        entity = cls.get_by_id(id=id_or_keyname, parent=kwds.get('parent'))
        if entity is None:
            entity = cls(id=id_or_keyname, **kwds)
            entity.put()
            return entity
        return None


  • google.appengine.ext.dbをgoogle.appengine.ext.ndbにすると新しいモジュールでなんとなく動く(だいたいのAPIは上位互換)
  • key_nameとidの区別がなくなって、key_nameを使っていたところはidを使うようにAPIが変更されている
  • 普通にput()とかすると、これまでどおりの処理が行われる(全然非同期じゃない)
  • 非同期処理を行う場合は、
    k1 = Key('モデル名', id)
    f1 = k1.get_async() # これで、値の取得が開始される
    <何か処理をする>
    a1=f1.get_result() # 取得結果を受け取る

    ということらしいです。(key_nameが無くなったことを知るだけで2時間くらい消費してしまった・・・。へこみました)

    確かに、自動でidを振られた場合と 自分でkey_nameを指定した場合で、使うメソッドが違うのは格好が悪いので、このほうが良いですね。

    だから、上の例みたいなラッピングはしないことがお勧めです(!)
    普通にget_by_idで統一しましょう。


2012/02/25 追記:
あれ、でも別にNDB使わなくても、昔から非同期でデータストアにアクセスできるんですね・・・。
GAE/PのAsync Datastore APIの使い方


その他の追加の機能(yeildで非同期アクセスの結果を受け取る書き方や、taskletsとか)や、設計上の不合理、新バージョンを押し付けない、ってのがメインなんですね・・・。


うーん?別にそんなにNDBにこだわる必要もないような?

2012/03/05 追記:
ここの記事見るより、こっちを見ましょう!
http://najeira.blogspot.com/2012/02/google-app-engineapindb.html