vimでPython環境を作る

『シャープを造った男 早川徳治伝』なんて本を読んだ。小百合さんが出てきたり、目の付け所が 違うって高感度なコマーシャルを流してるあのシャープ。昔はおいらも関数電卓のお世話になりました。

多少脚本してあるらしいけど、ほぼ史実に忠実に書かれているとか。シャープって関西系の 会社だと思っていたら違うのね。創業は東京だそうだ。繰り出し式鉛筆を地道な努力で 成功させ順風満帆だったけど、関東大震災で工場を無くし、妻子を亡くすと言う試練。

大阪の取引先を頼って、大阪へ出、そこで一からやり直し。持ち前の好奇心で鉱石ラジオの 国産化に成功。球のラジオ(並4)も出して大当たり。

ラジオを試作したはいいけど、試験放送もまだ無い時代。自前で電信の送信機を作って、それを 信号源に開発を続けたとか。バイタリティがすごいな。

やがて並4のラジオが5球のスーパーに変わった頃、目の付け所が有った徳治さんは、次は テレビだと勇敢にチャレンジ。国産初のTVを売り出し。

コンピュータもやりたかったけど、某5大メーカーに独占されてしまって撰外。ならば、八百屋 でも使えるコンピュータって事で電卓の開発に没頭。

まねしたの松下、早まったの早川(現シャープ)、モルモットのソニー(創業者は新しい物好きで 開発に取り組むので、それを揶揄したらしい)と、時代を作ってきた人達が以外な関係で 結ばれていたりして、非常に面白かったよ。

Python環境を作る

今まで、括弧言語中心にvimを見てきたけど、やっぱり普通の人も演じたい。そこでPythonですよ。 (括弧が少ないしね) FreeBSD9、ArchLinux、Windows7と言う、三角関係でも(一番)平等に動きそうだと思った からだ。

そんな訳なんで、FreeBSD9を入れる時もPython中心にいろいろ取り揃えておいたんだ。 で、すいすいとPythonに触るにはどうしたらいいか。一番長く触っているのはeditorだよね。

emacsでもいいんだけど、Pythonとは相性が悪そう(で苦労してる人を見かけた)なんで、 乗り掛けた船と思って、vimを使う事にする。長い前口上だ事。

pep8

何事も最初が肝心。Pythonには、 Python Enhancement Proposals (PEPs)なんてのが有る。 平たく言うと、Python界のRFCかな。その中にコーディング基準と呼ばれるものも入っている。 いわゆるPEP8がそれだ。

Pythonはスクリプトの書き方にぶれが無いのが特徴だけど、更にそれに*たが*をかけて、締め付けて あげようって訳。SMの世界です。そのための採点プログラムが用意されています。

早速vimから使えるようなものを探してきましたよ。 pep8 : Check your python source files with PEP8 自己採点しましょって事ですな。

FreeBSDでは幸いな事にpep8がパッケージになってたんでそれを入れてから、pep8.vimを配置して あげた。Windowsでは、gitで取ってきて、setup.py build してから、setup.py installした。

デフォでは、F5キーでチェックが始まるように設定してあるけど、絶対にそんなキー割付を忘れて しまう(自信有り)ので、.vimrcに、

let g:pep8_map='<F8>'

と書いて、脳内連想記憶が働くようにしておいた。早速、FreeBSDで試運転。対象は自分の唯一の 実用アプリである、血圧グラフ化プログラム。

F8キーを押すと、画面が割れて、QuickFix画面が登場する。ここに対象スクリプトの行番号と ご神託が出てくるんだ。ちょと恥ずかしいけど開陳してみる。

  :
 10 hi = []; low = []; pls = []      # buffer for stat
 11 mm = datetime.date.today().strftime('%m') # this month
 12 dirty = False                    # need to save ?
 13
 14 def save(v=''):
  :
---- ~/py/blood.py -----------------------------------------------------
py/blood.py|10| 8: E702 multiple statements on one line (semicolon)
py/blood.py|11| 42: E261 at least two spaces before inline comment
py/blood.py|14| 1: E302 expected 2 blank lines, found 1
  :
---- QuickFix Lisp :pep8 --repeat py/blood.py --------------------------

10行目はマルチステートメントでっせ。11行目は、ステートメントとコメント間が詰まり すぎでっせ。14行目は、def定義の前は2行分空けましょう。

QuickFixの該当行でリターンを叩くと、ソースの該当の場所に飛んでくれるんで、すいすいと 修正。セーブしてからもう一度チェックにかける って事を繰り返す。 そのうちに、正しい作法が身について、世界でも通用するようになるだろう。何せ、日本人は 礼節を重んじる国民ですから!

Windows7にも矯正装置を入れてみた。早速実行してみると

|| 'pep8' ??A???R?}???h?????O???R?}???h?A
|| ?€?i??\??v???O???€?????o?b?` ?t?@?C????μ??F? ̄?3?e??¢??1?n?B

こんな意味不明語が出てきた。(実際は、<82>A みたいなやつだけど、コピー時に文字化け**2 に なっちまったよ)

はてどうしたものかな? FreeBSDでは、pep8がコマンドになってたんで、Windowsも同じ事を 要求してるんだろな。

c:\>pep8 -h
'pep8' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。

上記の文字化けは、これが原本だったのね。FreeBSDではコマンドをどう構成してるんだろう? 参考に見ておくか。

#!/usr/local/bin/python2.7
# EASY-INSTALL-ENTRY-SCRIPT: 'pep8==0.6.1','console_scripts','pep8'
__requires__ = 'pep8==0.6.1'
import sys
from pkg_resources import load_entry_point

sys.exit(
   load_entry_point('pep8==0.6.1', 'console_scripts', 'pep8')()
)

で、Windowsの方にも同様なスクリプトを置こうとうろうろしてたら、C:\Python27\Scriptの 中に、pep8.exeが鎮座してた。単にPATHが通っていなかっただけの話ね。お粗末さん。

でも考えてみるに、ここまでまずい点を指摘してくれるんなら、そんなの自動修正してよ。 あんたコンピュータなんでしょ、と思うのは、正常な心の持ち主だと思うよん。 (そうでなかったら、既にあなたはコンピュータの奴隷です)

美容整形

少々出来の悪い人も、○○美容整形外科へ走るのが流行です。スクリプトも美容整形の時代です。 何百万円も請求される事はありませんので、安心してチャレンジしましょう。

と言う訳で、PythonTidyですよ。たまたま、FreeBSDの カタログに載っていたのを見つけておいたって訳。

昔々、同僚にPerl書きの女子が居たけど、その子、ネットから拾ってきたコード片をペタペタ 貼り付けていたんだ。挙句の果てに動きませんって泣きつかれて、Debug支援をやらされはめに。 そんな時、真っ先に行ったのが、perltidyによるコード整形。これをしとかないと、インデントが めちゃくちゃで読めたものではありませんでした。

まさかPythonにもそんなのが有るなんて露知らずでしたよ。

前書きが長くなっちゃったけど、試してみたら、一行野郎(のっぺらぼう)になったまったぜい。今の所はこやつ 、おれの所では悪徳整形美容外科に認定されちゃったな。内偵を進めて、そのうちガサ入れすっかな。 ちなみに、使い方はこんなだよね?

[sakae@secd ~/py]$ pythontidy blood.py after.py
[sakae@secd ~/py]$ wc blood.py after.py
     159     485    4173 blood.py
       0     503    4218 after.py

ビューティーコロシアムとかだと、ワァ綺麗って驚くのがお約束だけど、こやつは、超不細工に 整形されてしまいましただ。

そこで、お詫びと言っちゃ何だけど、 きちんとしたコードが書けるように下準備をしっかりしておく事にする。

Python Wikiのvimを参考にしつつ

filetype plugin on
filetype indent on
autocmd FileType python setl autoindent
autocmd FileType python setl smartindent cinwords=if,elif,else,for,while,try,except,finally,def,class
autocmd FileType python setl expandtab tabstop=4 shiftwidth=4 softtabstop=4

を追加しとくと、元からイケメンになれるかも知れない。(うわべだけだけど)

もっと参考書って人は、Useful VIM Settings とか Python and vim: Make your own IDE を参照。

Pythonで実行するぞ

そりゃもう、以前に入れたQuickRunで決まりでしょっと思っていたんだけど、自作の血圧スクリプトが 動かないんだ。それで血圧上がって、ぽっくり逝くのは御免だね。

どんな風に動かないかと言うとWindows7の場合、途中で引っかかっているっぽい。 嗚呼、引っかかると言うと、脳血栓を連想しちゃってヤダな。

C:\Windows\system32\cmd.exe /c "^"python^"  ^"C:\homes\WORK\blood.py^"  >C:\User
s\sakae\AppData\Local\Temp\VIoBEF8.tmp 2>&1"

こんな内容を持ったターミナルが鎮座したまま、麻痺しちゃうんだ。これってunix界隈の 流儀じゃありませんかね。試したスクリプトは、コンソール入出力を伴う物。きっと手足が 痺れているんだな。リハビリは諦めよう。

別の手を捜してみた。

" Execute python script C-P
function! s:ExecPy()
    exe "!" . &ft . " %"
endfunction
command! Exec call <SID>ExecPy()
autocmd FileType python map <silent> <C-P> :call <SID>ExecPy()<CR>

CTRL-Pって叩くか :Exec って叩けばスクリプトの実行が始まる。

C:\Windows\system32\cmd.exe /c python blood.py
Loaded 82 datas!!
02> stat
size:   82
min:    101.0   62.0   54.0
medean: 119.0   76.5   62.0
max:    136.0   85.0   72.0
mean:   119.3   75.6   62.7
std:      9.1    5.7    4.5
02> ^Z
Hit any key to close this window...

シンプルなvimスクリプトの割りには、ちゃんと動くな。特に、Pythonスクリプトの実行が 終了しても、そのままコンソールが残っている動作が気に入ったぞ。

Python complate

slimeでは補完が有った。長い関数名でも途中まで入力しといてTABを叩けば後に続く文字列を 補ってくれるやつ。vimでもきっと有るよね。emacsと張り合ってるんですもの。

vimスクリプトの巣窟 で探してみたよ。そしたら、 Pydiction : Tab-complete your Python code とか pythoncomplete : Python Omni Completion が、メジャーっぽい事が判明。

まずは、自前の補完用辞書を持っていて、さっと補完してくれそうなPydictionを試してみよう。 詳細な設定は、 こちらの方を参考に。

でも、動かなかったよ。何で何でと思って、必殺技 :scriptnames を繰り出して、vimスクリプトの ロード具合を確認したら、何とロードされてなかった。しょうがないので

set runtimepath+=~/.vim/after/

して、PATHを追加してあげた。そしたら動き出した。けど、候補の右側に出て来る辞書の在り処 が非常に無駄な事をしてるようで、おいら的にはいまいちだなあ。気を取り直して、もう一つの 候補を試してみる。

vimに元々備わっているオムニ補完と言うのを使うらしい。補完用関数を下記のように設定 して、ダイナミックにその場で補完するようだ。

autocmd FileType python set omnifunc=pythoncomplete#Complete

補完の開始は、CTRL-X CTRL-O らしい。(って、これじゃemacsじゃん!)

実際に(print)を補完させようと、prCTRL-X CTRL-Oしてみると、パターンは見つかり ませんですって。ここでしばし悩む。簡単なのは手打ちするのかな?

そうすると、importした複雑なやつは、しゃーない補完してやっかと腰を上げるんかしら?

execle(file, *args, env)

    Execute the executable file with argument list args and
    environment env, replacing the current process. 
--- [Scratch] ---------------------------------------------------
import os
os.execl(
      execl(file,...)
      execle(file,....)
      execlp(file,....)
      execlpe(file,....)
        :
--- ~/test.py ----------------------------------------------------

こんな具合に、画面が割れて、メソッド等の説明が出てきましたよ。こちらの方が 有意義な情報一杯で嬉p--。