本連載も今回で最後です。今までの知識に加えrandomモジュール
・stringモジュール
を用いてランダム文字列の生成を行えるようになりましょう。
また、最後にVimから外部プログラムを呼び出して自身のPythonコードを実行する手順も簡単にご紹介します。
環境
- OS X 10.11.6
- Python 3.4.4
最終的なコード
いままで上記を最終的なコードとしてきましたが、まず最初に長すぎる行のコード規約エラーについて回答を示しておきます。
区切りの良いところで改行を入れる
Pythonはカッコで囲まれた部分は改行を含んでいても連続したものとして認識してくれるという特徴があり、それを利用します。
import random import string digit = 8 random_str = ''.join( [random.choice(string.ascii_letters + string.digits) for _ in range(digit)]) print(random_str)
これで長過ぎる行は解消されました。しかし上記だと単に長い文を問題が発生しない位置で折り返しただけなので、スマートな解決策とは言いがたいですね。もっと構造的に見やすくしたほうが良いでしょう。
適切な変数を用意する
8行目、source
という変数を用意することによって見やすくしたということです。コード規約に怒られたから改行して回避するのではなく、アラートの意図を組んで対応したほうがより良いコードになるかと思います。
こちらの方が見やすいので、本コードで解説を進めていくことにしましょう。
モジュールのインポート
import random import string
一番最初にtools.py
とmain.py
の解説でしれっと使ってしまいましたが、モジュールのインポートはこのように行います。
モジュールというのはある機能に特化した道具箱みたいなものだと思ってください。
randomモジュール
はその名の通りランダムに関する処理を、stringモジュール
はその名の通り文字列に関する便利な道具がいっぱい入っています。*1
また、モジュールというと仰々しい感じがしますが、中身は単純なPythonファイル(モジュール名.py
)です。
そんな便利なものだったら最初から入れておけばいいじゃないかと思われるかもしれませんが、最初からてんこ盛りの状態では非常に重くなってしまうので、起動時は身軽な状態でスタートし、必要に応じてインポートするという仕組みになっています。
モジュールを使ってみる
例としていくつかモジュールを使ってみましょう。すでにインポート済みの状態とします。
randomモジュール
random.randintメソッド
random.randintメソッド
はランダムで整数を取り出すメソッドです。
random.randint(1, 5)
この例では実行するたび1
, 2
, 3
, 4
, 5
を取り出します。
random.choiceメソッド
random.chiceメソッド
は引数にシーケンス型*2をとり、そこからランダムで取り出します。
random.choice('abc')
上記例では実行するたびa
,b
,c
をランダムで取り出します。
stringモジュール
string.ascii_letters定数
すべてのアルファベットであるabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
を取り出すことができます。
string.digits定数
数字0123456789
を取り出すことができます。しかし、注意すべきはこれはstringモジュールの定数
だということです。つまり取り出した数値は文字列型です。
すべてを組み合わせる
今までの知識を総動員してコードを読んでみましょう。
source = string.ascii_letters + string.digits random_str = ''.join([random.choice(source) for _ in range(digit)])
上記コードを分解していきましょう。
ランダム文字列のベースとなる文字列+数値を用意する
source = string.ascii_letters + string.digits
前述の説明の通り、source
の中身はabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
となります。
リスト内包
[random.choice(source) for _ in range(digit)]
次にここ、内包表記ですね。rangeオブジェクト
の引数にdigit
が渡っていますが、これは桁を意味している変数で自分で決めたものです。ファイル名を8桁のランダムにしたければ8を、4なら4桁になります。そして添字は使用しないので_
としています。つまりfor _ in range(digit)
の部分は単純にdigit
の数だけループするという意味になります。
つぎにrandom.choice(source)
の部分です。これはsource
からひとつ抜き出すという意味です。
そしてこれをリスト内包としたことで、アルファベットと数字から1文字抜き出したものをdigit個だけ要素に持つリストができあがったわけです。
最後に説明していなかったjoinメソッド
ですが、これは文字列を要素に持つイテレート可能オブジェクトの各要素をつなぎ合わせた文字列を返すメソッドです。
これも例を用意しましょう。
joinメソッド
print(''.join(['a', 'b', 'c'])) # abc print('-'.join('arigato')) # a-r-i-g-a-t-o print('☆'.join(('つのだ', 'ひろ'))) # つのだ☆ひろ
''
(シングル・ダブルクオーテーション)の中に文字列を入れると、その文字列でイテレート可能オブジェクトの要素一つ一つをつないで返してくれます。
これでめでたくアルファベットと数字からなるランダムな文字を指定回数だけつなげた文字列を得ることができました。
Vimから外部プログラム呼び出し自分自身をPythonで実行する
Pythonコードが本連載のメインなので、ここは簡単に動画の手順だけ解説します。
treeコマンド
で現在のディレクトリの内容を確認$ vim create_rand_filenames.py
コマンドを実行:!python %
で現在のファイルを外部プログラムで実行- vimに戻ったら
C-z
でvimを中断 command + K
で画面をクリア(後のtreeコマンド
が長いため)treeコマンド
で現在のディレクトリの内容を確認。ファイルが生成されているのが分かる
まとめ
いかがでしょうか。駆け足で説明したため割愛した箇所も多かったですが、大体の雰囲気はつかめたかと思います。このツールは他のスクリプト言語でも実装できますが、Pythonもぜひ候補に入れてみてください。
備考
今回はもともと複数ファイルのリネームがメインの記事だったので、ある程度の個数ファイルが生成されていればよかったため、このような実装になっています。forループ
は10回ですが、低い確率で同じファイル名が出ることもあるでしょう。
'w'
オプションでopen
を実行した場合、同じファイル名では上書きになるのがPythonの仕様でした。つまり確実にループ回数だけファイルを作成するという処理を実現するためには、本コードを改造する必要があります。
色々なやり方があると思うので、ご興味がある方はトライしてみてはいかがでしょうか。