kick the base

Houdiniと、CG技術と、日々のこと。

Python: ランダムなファイル名を持つテキストファイルを複数作成する1 -forループ・添字と__name__属性

前回MacのFinder機能のみで複数ファイル名を変更する方法について解説しました。

その際ランダムなファイル名を持つテキストファイルを複数作成するツールをPythonで作成したので、今回からそのPythonコードを1行ずつ解説していきたいと思います。

たった14行のコードですが、Pythonの基本が詰まっているので初学者には学びがあるかもしれません。

  • __name__属性について
  • forループについて
  • 使用しない添字と_(アンダーバー)について

今回は上記について説明します。

本ツールはRubyやPerl、AppleScript、JXA(JavaScript for Automation)等々でも可能だと思います。しかし3DマンとしてはちょっとしたツールもPythonで作りたくなるものです。

Yes. We are Pythonista.

さて、コードの解説に進みましょう。

環境

  • OS X 10.11.6
  • Python 3.4.4

最終的なコード

前回も軽く触れましたが、本コードにはPEP8規約に準拠していない部分があります。Pythonで本格的なアプリケーションを作成する場合には準拠すべき規約なので、本連載の最終記事にてその対応方法も載せておきます。

if __name__ == '__main__':ってなんだろう

よく見かけますね。if __name__ == '__main__':。まずはこれを解説するために、下記ふたつの簡単なPythonコードを用意しました。

tools.py

def total(*args):
    print(sum(args))


if __name__ == '__main__':
    print('This is debug.')
    total(3, 5, 7)

main.py

import tools

tools.total(2, 10, 100, 1)

tools.pyには可変長引数*1を全部足した結果を出力するだけの関数totalを定義しています。ここで、tools.pyとmain.pyを実行した出力結果を見てみましょう。

tools.pyを実行

$ python tools.py
This is debug.
15

main.pyを実行

$ python main.py
113

この結果の違いは何でしょうか。

実はif __name__ == '__main__':の部分はそのファイルを直接実行されたときのみ処理されるのです。main.pyからモジュールとして読み込まれた場合は実行されません。

つまり、自作のモジュールを作る際、デバッグ用の処理などを書いておくと便利なわけですね。この処理はソースコード上でよく見かける割に、書籍などで学ぼうと思うと後の方に出てくる知識なので、簡単に解説しておきました。

今回作成したツール、create_rand_filenames.pyは単独のツールなので、外部から呼ばれることはないためこのif __name__ == '__main__':の部分は不要なのですが、モジュール作成の基本なので入れています。

Pythonのループ処理

どの言語でもおなじみのforループです。while文もありますがここでは触れません。

Pythonのforループは下記作りになっています。

for 添字 in イテレート可能オブジェクト:
    ループ処理

イテレート可能オブジェクト*2にはrangeオブジェクトを用意することも多いのですが、このrangeオブジェクトはPython2系と3系で型が変わっていることだけ知っておくと後々何かと良いかと思います。下記コードを2,3系で実行した結果を示しておきます。

for i in range(5):
    print(i)

print(type(range(5)))

2系の出力結果

0
1
2
3
4
<type 'list'>

3系の出力結果

0
1
2
3
4
<type 'range'>

不使用な値とアンダーバー

Pythonではアンダーバーに関する下記ルールがあります。

  • __変数という変数名を定義すると、外部からアクセス出来ない変数を生成できます。これを外部にアクセスさせるには、アクセサメソッドを介します。

  • _変数とすると外部からアクセスしてほしくない変数を表します。暗黙の了解として使用し、機能的には外部からアクセス可能です。

このことから、実際使用しない値には_を用いるという慣習があります。(主にタプルで使用するケースが見受けられます)

よってぼくはforループなどでも添え字を使用しない場合には_で定義することにしています。

for _ in range(5):
    print('OK!')

出力結果は下記のとおりです。

OK!
OK!
OK!
OK!
OK!

コールドリーディングの参考としてみてください。

まとめ

特に__name属性__についてはよく見かけるコードかと思います。うまく活用してみてください。次回も基本的な内容が続きます。

*1:可変長引数とは個数の指定をせず複数の引数を扱えるフォーマットです

*2:イテレート可能オブジェクトをちゃんと説明するとそれだけで一つの記事になってしまうので、ここでは簡単に「呼びだすと次々要素が出てくるもの全般」という感じでふわっとお茶を濁しておきます