Responder in paradise[1] ほんとの第一歩

これの続き。

PythonでResponderというと、サンプルとして必ず出てくる

import responder

api = responder.API()

@api.route(“/”)
def nanntarakanntara(req, resp):
………

な感じのアレ。恐らくFlaskユーザへのラブレターなんだろうが、Flaskを知らないユーザはアレを見てどう思うだろう?

俺は最初「 最も重要なAPIのインスタンスがグローバルな場所に無操作に置かれている」のが嫌で、これを自前クラスの中でself.apiとした。ところがこれだと@デコレータでのルーティングができない(!)。

この時点で心折れそうになったが気を取り直して本家ドキュメントを読み、その代替手法たるadd_route()の存在を知った(たぶんfalcon伝)。そしてその結果、ルーティングにクラス内のメソッドを使えるようになった。

が、これだけだといずれクラスの肥大は免れない。そこで更に「クラスベースのルーティング」を試してみることに。やり方は簡単でadd_routeの第2引数にクラスの名前を書くだけ。これでresponder.apiのクラスと、ルーティングの対象に応じて使われるクラスとが分離されてスッキリした。

がしかし、今度は後者でapi.templateを使おうとして躓いた(分離したのだから当然だが)。暫し悩んだ後、後者をインスタンス化して__init__でapiを渡し、add_routeにはクラス名でなくそのインスタンス名を書いてみたら○。

という訳で結構苦労したが、ここまででルーティングの手法を「デコレータとメソッドで」から「add_routeと別クラスで」へとすることができた。この拘りはいずれ己を救うと信じている。以上!

Responder in paradise[0] はじめに

長いことWeb方面で食ってきたこのワタクシが昨年Embeddedな世界に戻ってきて以来、自分でも呆れるくらいずっとPython漬けな日々が続いている。おかげでいまやPHPとかJavaScriptとかに強烈な違和感を覚えるようになり、もはや併用は無理と判断するに至った。そして遂には、ApacheやPostgreSQLとの組み合わせで20年近くも使ってきた前者を「すっぱり捨てる」覚悟を決めた。そこでまずは定番Djangoから始めてみたが、すぐに「俺にこの思想は向かない」と感じ、以後最近この界隈で話題のResponderで行くことに決めた(注1)。

とはいうもののResponderはまだデビューから間もないとあって、情報が圧倒的に不足している(注2)。そこでここは一念発起、自らResponderの「人柱」となるべく備忘録を兼ねてこのスレッドを始めることにした。いわゆる「はじめてのResponder」は数多のヨソ様におまかせするとして、ここではその応用編・実用編、それもPHP(とかPerlとか)から流れてきた人向けという感じな展開ができればと思っちょります。乞うご期待!

次回「ほんとの第一歩」に続く

注1: FlaskでもFalconでもない理由は既に多くの人が語っているので省略
注2: 現在本家サイトにhttpsでアクセスできないし …

世界の中心で改めて「WindowsはXXX!」と叫ぶ

またかと言われそうだが、俺はWinがすかん。その理由はたくさんあるが、イチバンのそれがCP932とかいう内部エンコーディング。今回、久々にその地雷を踏んでしまった。足を離して木っ端微塵になる前に、自戒を込めてグチる。

普通な欧米人には理解できないであろう変な文字列(ex:日本語)をインターネットな世界で一緒くたに扱うのにUTF-8は、いまやごく普通であり常識である。そう、何もかもUTF-8でやっていればみんなハッピー、誰も困らないのである。実際AndroidもiOSもMacもLinuxもとっくにそうなっている。が、WinだけがいまだにCP932という「無意味どころか害でしかない」エンコーディングを改めようとしていない。結果、それをそのままファイルに書き出し→インターネットな処理系でそれを読む→機種依存文字の変換不可→DEAD … ある時期までは「よくある話」だった。

が、それって20年も前のこと。それをこの期に及んで食らうとは迂闊だった。更にタチが悪いのは、こういうのを「致命的な問題」と言っても、まず意味がその相手に通じないこと。「手遅れか!」と気づいた時はもう遅い。

まとめ:MSなServerとかSQLとかなシステム = 対人地雷。いずれ絶滅するが、それまでは探知に努め踏まないよう注意すること.。

Possible mission

20年以上も前に作られた「ある」システムの「ある」部分を作り直せとの命令が下った。ここで最初の難敵は「ビッグエンディアンなバイナリファイル×多数」。要はその当時のMotorolaな処理系(弔)がファイルに吐き出したCの構造体で、これをそのまま最新のリトルエンディアンな環境で編集せよというのである。

このような「どこの誰がいつ作ったのかわからんフォーマットへの後方互換」は、いちばんやりたくないところだが仕方ない。最初はそこ(読み書き)だけCで書いてPythonから呼ぼうかとも思ったが、エンディアンの整合を考えただけでウンザリ。何かいい手はないか? と調べていて行き着いたのがctypes.BigEndianStructure。こいつで構造体のメンバーを定義してインスタンスを作れば、エンディアンの違いを(殆ど)意識する事なくプログラミングができる。名称からしてそのものズバリな、こういうのをハナから使えるところはさすがPythonである。

ただ、だがしかし …

こういうのって、そもそもエンディアンの意味とCの構造体とが理解できてなきゃ無理=「書く」手間より「読む」手間の方がかかる。なので、Cプログラミングの経験のない若者には敷居が高い。するとやはり、このワタクシを始めとする「Cで稼いできた旧きエンジニア」ならではの仕事なのかなあ、と思うと複雑な心境。俺もビッグエンディアンと共に絶滅種入りか? … おおコワ!

「データクラス」への期待

これの続き。

Pythonのdictは柔軟で扱いやすいが、一方で値の型が把握しづらい(注1)。他人が書いたコードは言わずもがな、自分の書いたそれもすぐ忘れて「?」となる。またその入れ子やら新たなキーの追加や削除やらも容易だが、こういうの(注2)をやりだすと状況は更に悪化する。Cの構造体のようなカッチリとしたデータ構造を記述するにはどうしたら良いのか? Python3.7から導入された「データクラス」は、そうした要望に対する回答のひとつである。

何よりdictではできない「継承」が使えるだけでも有り難い。実をいうとその存在に気づくまで、俺は通常のクラスでこれをやっていた。そういう意味では「データクラス=データ保持に特化したクラス」と捉えて差し支えない(注3)が、便利な機能が多数盛り込まれているので「これからは遍くこれで」と考えている。

惜しいかな現時点ではクラス変数に不正な型を代入しても動いてしまうし、PyCharmでも警告が出ない。が、これらが実現されるのはそう遠い先の事ではないと思う。尤もそうなるともはやPythonは「動的片付き言語」と呼べなくなるのでは? だが、俺的にはその方がずっといい。

注1: 変数では有効なtypehintがdictのキーには使えない
注2: Pythonに限った話ではなくPHPとかJavascriptとかも同様である
注3: 実際データクラスはclassへのデコレータで記述する

型あるものいつかは助かる

このワタクシも「アセンブラで育ちCで稼いだ世代」なもので最初は「動的片付き言語」が苦手だった。が食うに困って何事も勉強とPHPとかJavascriptとかを使うようになって以来「アレはアレ、コレはコレ」という切り分けができるようになって幾年月、ここ暫くはPythonにすっかり軸足が移っている。ちょいプロにはこれが最適である。

だがその規模が大きくなってくるとやはり「前に自分の書いたコードが理解できない」というクライシスにしばしば陥る。またそうなると、変数や関数の型が曖昧なところが更なる混乱を招く。

そこである時期から変数の定義にはtypehintを、関数の定義にはキーワード引数をと心掛けるようになって状況は大きく改善した。尤もそれらはPythonのというよりむしろ「Pycharmの助け」あってというところだが、結果良ければ全て良しである。なので以前に書いたコードを片っ端からこれらで書き換えた = ここまでは意図したとおりだった … が、ひとつ面倒なやつが残った。

dp = {
    'name': 'sekitakovich',
    'age': 18,
    'valid': True,
    'at': dt.now(),
}

こういうCのstructure的な書き方をしている部分が綺麗に書けなくて困っていたんだが、Python3.7のドキュメントで目にした「dataclasses」なるキーワードからこれが一気に氷解した。

# 詳細については改めて!