2018年3月28日水曜日

Hello Python

この文書作成時の環境は以下です。

  • Windows 10 professional バージョン1703
  • Chocolatey v0.10.8
  • Python v3.6.4:d48eceb
  • PyCharm Community 2017.3.3

小規模なスクリプトにPythonを使いたい

ログとかをごちゃごちゃ弄るスクリプトは今までbatやPowerShellを主に使ってきた。
PowerShellはともかくbatは二度と書きたくないので、高級言語で簡単なスクリプトを書けるようになろうってんでやり玉に挙がったのがPython。なんか最近人気みたいだし。1 何よりparseargsっていうコマンドラインパーサが標準で用意されているらしい。これがとても魅力的だった。

チュートリアルを上から順番にやるってめんどくさいじゃん

この考えはあんまり良くない考え方だと思うけど、事情により「学習のための時間」が取れないことだってあるのだ。
Pythonをこれから長期的に使っていくとした場合、チュートリアルを上から実践していくのが、最終的にコストが小さくなるであろう。
時間があるならチュートリアルを上から順番にやればいいし、今後やるつもりだがすぐに動くスクリプトを要求されたので付け焼刃でPythonスクリプトを書いていく。

とりあえずPythonを使えるようにする

chocolatey2 使えば一発よ。chocolateyはwindowsの標準であるところのPackageManagement3 よりもパッケージが充実しているのでオススメ。

PowerShell(管理者)
> cinst python3

ついでにPythonのIDEであるPyCharmも入れとこう。JetBrains製のIDE好きよ。

PowerShell(管理者)
> cinst pycharm-community

PyCharmの起動は置いておいて、Pythonのインストールが完了したらおもむろにPythonインタプリタを起動

PowerShell
> python

インタプリタでHelloって言うとHelloって返してくれる。Pythonは挨拶ができるいいやつだ。

Pythonインタプリタ
>>> 'Hello'
'Hello'

Python版Hello World!

Hello.py
#! /usr/bin/env python
# -*- coding: utf-8 -*-

import sys

sys.stdout.write('Hello World!')

まあなんとなくわかる。

shebang行

#! /usr/bin/env python
shebang(シェバン)行と呼ばれるものらしい。
3. Windows で Python を使う — Python 3.6.4 ドキュメント
Linux環境で./Hello.pyと実行したときに/usr/bin/env pythonに解決されることを意味するようだ。
詳しくは呼んでいないがWindows環境でも書いておくと可搬性が上がるらしい。

マジックコメント

# -*- coding: utf-8 -*-
ソースコードの1行目または2行目にソースコードのエンコード形式を記載するらしい。
デフォルトはUTF-8なので冗長ではあるけども、もしかしたら今後デフォルトのエンコード形式が変更になるかもしれないのでおまじない的に書いておくのがいいのかな?
2. Python インタプリタを使う — Python 3.6.4 ドキュメント

標準モジュールの読み込みと利用

pythonの標準モジュールであるsysモジュールを読み込み、利用している。

sys モジュールは、全ての Python インタープリターにビルトインされています。
6. モジュール (module) — Python 3.6.4 ドキュメント

とのこと。
こちらを利用して標準出力にHello World!を出力している。

なんか作ってみる

(必要に迫られたので)ディレクトリ内のテキストを結合するツールを作成する。
Pythonを使わずとも、あるいはPythonでももっと簡単な方法があるだろうけど、あえて不慣れなPythonで。

できたものがこちら。

Merge.py
#! /usr/bin/env python
# -*- coding: utf-8 -*-

import sys
import argparse
import os

parser = argparse.ArgumentParser()
parser.add_argument('srcDir', help='Target directory contains txt', type=str)
parser.add_argument('-d', '--deleteSrc', help='delete merged source files')
args = parser.parse_args()

if not os.path.isdir(args.srcDir) :
    sys.stderr.write('argument [srcDir] is not directory.')
    sys.exit(1)

for filename in os.listdir(args.srcDir) :
    path = os.path.join(args.srcDir, filename)
    if(os.path.isdir(path)) : break
    with open(path, 'r', encoding='utf_8_sig') as f :
        for line in f:
            sys.stdout.write(line)

特徴的なのはオフサイドルール4に従ってブロックが記述されていることだろうか。

文、変数の代入、関数呼び出し

Merge.py
parser = argparse.ArgumentParser()
parser.add_argument('srcDir', help='Target directory contains txt', type=str)
parser.add_argument('-d', '--deleteSrc', help='delete merged source files')
args = parser.parse_args()

動的型付けで特に宣言なくいきなり変数に代入が可能な模様。(型ヒントは存在するようだ5
関数呼び出しはxxx(引数, 引数)という形式。文は改行で区切るのが普通らしい。

条件分岐

Merge.py
if not os.path.isdir(args.srcDir) :
    sys.stderr.write('argument [srcDir] is not directory.')
    sys.exit(1)

if文。条件式は()でくくらないのが普通らしい。
論理演算がnotandなどの英単語なのが読みやすくておしゃれ。
ちなみに、elseifではブロックが深くなっていって具合が悪いのでelifというキーワードを用いる模様。
また、Pythonで共通してブロックの開始は:でブロックの終了はインデントが戻るところ。

繰り返し

Merge.py
for filename in os.listdir(args.srcDir) :
    path = os.path.join(args.srcDir, filename)
    if(os.path.isdir(path)) : break
    with open(path, 'r', encoding='utf_8_sig') as f :
        for line in f:
            sys.stdout.write(line)

今回はリストのイテレーション。
for x in xxx :でxxxコレクションの中身をイテレーションするみたい。
withはC#のusing構文やJavaのtry-with-resource構文に相当するキーワード。ブロック終了で資源が回収されるらしい。

やってることは全部のファイルを全部のファイルごとに一行ずつ標準出力に書くとか頭の悪いことしてるので、もうちょっと頭良く処理する例を作ればよかった。

感想

ブラックボックスで構わないちょっとしたツールなんかを作るときは便利だな~って感じ。

  • 可読性に重きを置いた文法に思える
    • 現状読みなれていないので本当に読みやすいかどうかはわからない
  • 標準ライブラリが豊富
    • ライブラリの選定が必要ないのは大きな利点

0 コメント:

コメントを投稿