●
先日の「C# CSVファイル、CSVリソースを配列化する関数」ですけどね。C#書くのは楽しめたけど、やっぱり「お気に入りのpyてょんと比べてどうも長ったらしいな」と、思ったわけよ。というわけで「1日1Python」の時間です。あっちと比べてホントに長ったらしいのか、実際にPythonで同じものを書いて試してみようじゃねーか。
あっちと同じ順番で書いてみる。
- 改行を含むCSVファイルを用意
- CSVをリソースに追加
- 今回作ったCSV二次元配列化関数
- 作った二次元配列を確認する関数を準備
- 実行
- 結果 (7. exe化)
●
1. 改行を含むCSVファイルを用意しとく
0,緑色,Midori-iro,"みどりいろ"
1,うぇる,Weruda,"ウェル
ダ"
これは前と同じ。
2. CSVをリソースに追加しとく
「リソースに追加する」ってのはC#だと「Visual Studioのリソース欄に追加する」って意味になるけど、そんなコトはpythonじゃできん。だけれど、CSVファイルをexeファイルに含めることはできないけれど、pyファイルをexeファイルに含めることは当然できることから、「CSVファイルの中身をpyファイルに埋め込んでpyファイルとしてプログラムに埋め込む」っつー手法を思いついた。以下のようなファイルを DEFAULT_CSV.py として準備。
# coding: utf-8
text = '''
0,緑色,Midori-iro,"みどりいろ"
1,うぇる,Weruda,"ウェル
ダ"
'''
3. 今回作ったCSV二次元配列化関数
import os,sys,csv,pprint
import DEFAULT_CSV # デフォルトのCSVをこういう形でリソース化
from io import StringIO # 後述。python2と3で読み込み方が違うトコ注意
# カレントディレクトリをプログラムのある場所、
# あるいはexeファイルの場所に移動する
def cd_():
# cx_freezeで固めるとコレがTrueになる。
if hasattr(sys, 'frozen'):
os.chdir(os.path.dirname(sys.executable))
else:
os.chdir(os.path.dirname(os.path.abspath(__file__)))
cd_()
# 二次元配列化の関数
def foo(csv_path, default_csv_module):
lis = []
if os.path.isfile(csv_path):
# しーえすぶい.csvがあればそれを使う
print('しーえすぶい.csvを使います')
with open(os.path.realpath(csv_path), 'r', encoding='UTF-8') as f:
for row in csv.reader(f):
lis.append(row)
else:
# ない場合はリソース(DEFAULT_CSV.py)を使う
print('DEFAULT_CSV.pyを使います')
for row in csv.reader(StringIO(default_csv_module.text.strip())):
lis.append(row)
return lis
カレントディレクトリ移動は「一石二鳥」とか「DialogFrame」あたりで学んだマイノウハウ。exe化するスクリプトには、なんとなくこれをつけておかないと不安になっちゃうだけで、本件にはあんまり関係ない。
StringIOモジュールは、手順2で用意した文字列をファイルオブジェクトに変換するのに必要。csv.reader()は文字列を直接扱ってはくれないようで、このワンクッションがいるみたい。
4. ついでに、作った二次元配列を確認する関数を準備
pprintを使うんで作る必要なし。pprintサンにはいつもお世話になってます。
5. 実行
# リソース用の引数にはモジュールをそのまま渡す
a = foo('しーえすぶい.csv', DEFAULT_CSV)
pprint.pprint(a)
6. 結果
オーケイだね。
7. exe化
ついでに今回のスクリプトのexe化に使ったcx_freeze設定を。以下のexe化ファイルを python cx_freeze.py build
で実行。
# cx_freeze.py
import sys
from cx_Freeze import setup, Executable
exe = Executable(
script = 'csv_read.py',
# 出力が欲しいプログラムではbaseをNoneにするコト。
base = None,
)
setup(
name = 'CSVread',
version = '0.1',
executables = [exe],
)
●
8. 結論
長さでいえば当然、pythonに軍配が上がったかな。でもそれ以上に、CSV文字列を埋め込んだpyファイルをC#でいうところのリソースとして扱うっつー思いつきが面白かった。この我流感!