質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

PyInstaller

PyInstallerは、Pythonのスクリプトを一括でWindowsなどで動く実行可能ファイルに変換できるツールです。このツールを用いることで自作のPythonプログラムを別で使用する場合でもPythonをインストールする必要がありません。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

3回答

11487閲覧

pyinstallerでcsvファイルを読み込む方法がわからない

vaitarika

総合スコア29

CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

PyInstaller

PyInstallerは、Pythonのスクリプトを一括でWindowsなどで動く実行可能ファイルに変換できるツールです。このツールを用いることで自作のPythonプログラムを別で使用する場合でもPythonをインストールする必要がありません。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

1グッド

0クリップ

投稿2019/02/27 07:34

編集2019/03/18 09:09

pyinstallerを用いてpythonスクリプトをアプリ化しようとしています。
そこで自分がアプリ化するプログラム内ではcsvファイルを用いるのですが、csvファイルをアプリ化した後に読み込む方法がわかりません。
pyinstallerでアプリ化する前はcsvファイルを読みこみプログラムを実行できるのですが、アプリ化した後では実行する事ができません。

自分の作っているプログラムのディレクトリ構成は以下の通りです。
file
|-main.py
|-sub.py
|-sub2.py
|-*.csv

mainスクリプトの中でsub.pyとsub2.pyをimportして使っており、sub.py内でcsvファイルを読み込ませて動作を行なっています。
csvファイルをsub.pyにおいて読み込ませるには下記のように記述しており、カレントディレクリからそのまま読み込むことを想定しています。

python

1with open("*.csv", "r") as f:

pyinstallerの性質から、main.pyのみを指定して下記のように入力してアプリ化させました。
コンパイルは以下のように行なっています。

pyinstaller --windowed main.py

これでdistファイル内に生成されたアプリを実行しようとすると何もおこらないため、アプリの「パッケージの内容を表示」させ、その中にあるUnix実行ファイルのmainを開いてやると、次のエラーがまず表示されました。

File "site-packages/PyInstaller/loader/rthooks/pyi_rth__tkinter.py", line 28, in <module> FileNotFoundError: Tcl data directory "/Users/~~~/Desktop/file/dist/main.app/Contents/MacOS/tcl" not found. [68860] Failed to execute script pyi_rth__tkinter

これと同様に、tclがtkに変わったエラーも表示されたので、MacOS下にtclとtkという名前のファイルを作ったところこのエラーは消えました。次に出てきたエラーがcsvファイルの読み込みに関するもので以下のエラーが表示されました。

File "main.py", line 5, in <module> File "<frozen importlib._bootstrap>", line 971, in _find_and_load File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked File "<frozen importlib._bootstrap>", line 665, in _load_unlocked File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/PyInstaller/loader/pyimod03_importers.py", line 627, in exec_module exec(bytecode, module.__dict__) File "sub.py", line 4, in <module> FileNotFoundError: [Errno 2] No such file or directory: '*.csv'

*.csvファイルを読み込むことができていないようだったので様々なディレクトリにcsvファイルを配置したのですが、このエラーは消えませんでした

sub.py内で同じ階層のディレクトリからcsvファイルを読み込むようにしていることが原因でしょうか。
どのように書き換えればcsvファイルをアプリでも読み込む事ができるようになるでしょうか。

pythonは3.6.6を使用しています。

tachikoma👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tachikoma

2019/03/18 08:12

ディレクトリ構成とファイル読み込みが失敗するコード、コンパイル方法、実行方法を質問に追記お願いします。
vaitarika

2019/03/18 09:04

修正依頼ありがとうございます。 質問に追記させていただきました。
guest

回答3

0

ベストアンサー

下記のようにsubからファイルを読み込ませると、うまくmain.pyの内容を読み込めてるんですよね。このあたりの確認から初めてみてはどうでしょうか。

main.py

python

1from sub import load_mainpy 2 3if __name__ == "__main__": 4 contents = load_mainpy() 5 print(contents)

sub.py

python

1def load_mainpy(): 2 with open("main.py") as f: 3 contents = f.read() 4 return contents

コンパイルと実行

sh

1$ tree -L 1 . 2. 3├── main.py 4└── sub.py 5 6$ pyinstaller --windowed main.py 7... 8$ ./dist/main/main 9from sub import load_mainpy 10 11if __name__ == "__main__": 12 contents = load_mainpy() 13 print(contents)

OSX 10.14.3
Python 3.7.0
PyInstaller 3.4

投稿2019/03/18 09:32

tachikoma

総合スコア3601

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

vaitarika

2019/03/18 10:25

回答ありがとうございました。 確かに上のプログラムを実行してみたところmain.pyが表示されました。 自分の作成したプログラムではsub.pyの中でcsvファイルを読み込んでそれを用いてsub.pyの中で処理を施すというものなのですが、sub.pyの中身をmain.pyに組み込んでみたところ、エラーメッセージが少なくなったのですが結局csvファイルは読み込めないようです。エラーメッセージは以下のものです File "main.py", line 7, in <module> FileNotFoundError: [Errno 2] No such file or directory: '*.csv' [69488] Failed to execute script test
tachikoma

2019/03/18 10:30

んーこれってpython main.pyでちゃんと実行できるスクリプトなんですよね?
vaitarika

2019/03/18 12:33

返信ありがとうございます。 main.pyで実行できるスクリプトです。csvファイルを読み込むときのパスとかの問題かと思っているのですが、csvファイルをどのように読み込ませればいいかわかりません。
vaitarika

2019/03/18 12:35

教えていただいたmainとsubはどのようにcsvファイルの読み込みと関係させればよいのでしょうか。
tachikoma

2019/03/19 00:32

上記の内容は、次にmain.pyの階層にsample.csvを作ってそれを読み込めるか確認してみる。うまくいけばさらに実際の条件に近づけていって、どこで失敗するかを探る、という具合です。
vaitarika

2019/03/22 07:36

返信ありがとうございます。 回答していただいたmainとsubのプログラムでsub.pyの with open("main.py") as f: の「main.py」の部分を自分の持っているcsvファイルの「sample.csv」に変えて ・ ├── main.py └── sub.py └──sample.csv というような階層を作り、main.pyを実行したところ、csvファイルは読み込まれており、csvファイルの内容が表示されました。 しかし、このmain.pyをpyinstallerで pyinstaller --windowed main.py としてアプリ化して、distファイル内に生成されたアプリを実行しようとすると何もおこらないため、アプリの「パッケージの内容を表示」させ、その中にあるUnix実行ファイルのmainを開いてやると、次のエラーが表示されました。 File "main.py", line 4, in <module> File "sub.py", line 2, in load_mainpy FileNotFoundError: [Errno 2] No such file or directory: 'sample.csv' やはりアプリ化するとcsvファイルは読み込まれていないようでした。
guest

0

元のコードが読むとおりの場所にCSVファイルを置けばいいのでは

投稿2019/02/27 07:39

y_waiwai

総合スコア87719

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

vaitarika

2019/02/27 08:17 編集

回答ありがとうございます。 exam |--main.py |--resource-- *.csv 上記のような階層にプログラムを作ってCSVファイルを読み込んで使っているのですが(main.pyの中でpath="resource/*.csv"として読み込ませている)、main.pyにpyinstallerを使って exam |--main.py |--resource-- *.csv |--dist--main.app とmainのアプリができた場合どのようにcsvファイルを配置させれば良いのでしょうか。
y_waiwai

2019/02/27 08:21

元のコードのとおり、exe化したファイルの場所にresourceというディレクトリを作り、その中にCSVファイルを配置しましょう
vaitarika

2019/02/27 08:38 編集

返信ありがとうございます。 申し訳ありません。先ほどお伝えしたものと自分の階層が異なっていました。実際は exam |--main.py |--sub.py |--resource-- *.csv という階層になっていて、mainがsubをimportして使い、subの中でcsvファイルを使うという形式になっています(sub.pyの中でpath="resource/*.csv"として読み込ませている)。 ご指摘いただいたように下記のように階層を組んだのですが exam |--main.py |--sub.py |--dist--main.app ______|--resource-- *.csv csvファイルが見当たらないというエラーがやはり出てしまいました。 このことはmainがsubをimportして使っていることと関係しているでしょうか。
y_waiwai

2019/02/27 08:39

そのエラーメッセージに書いてあるパスにCSVファイルを配置しましょう
vaitarika

2019/02/27 08:52 編集

返信ありがとうございます。 エラーが出た場所に配置したのですがそれでも変わりませんでした。 また、今回エラーが吐き出されたpythonスクリプトが "pyimod03_importers.py" であり、その場所が /PyInstaller/loader/pyimod03_importers.py" だったのですが、これを実行して見たところ、以下のエラーが吐き出されていました。 File "pyimod03_importers.py", line 27, in <module> SYS_PREFIX = sys._MEIPASS AttributeError: module 'sys' has no attribute '_MEIPASS' これは今回のcsvファイルが読み込めないことと関係しているでしょうか。
y_waiwai

2019/02/27 09:02

それはCSVファイルが読めない、というのとはまた別のエラーです。 ファイルはきちんと読んでるのでは。
y_waiwai

2019/02/27 09:03

sys には_MEIPASSってのはない、というエラーに見えますが。 そのエラーの該当行をチェックしてみては。
vaitarika

2019/02/27 09:38

上記のエラーを検索して見たところ def resourcePath(filename): if hasattr(sys, "_MEIPASS"): return os.path.join(sys._MEIPASS, filename) return os.path.join(filename) この関数を定義すればよいとあったので定義したのですが、次は Error loading Python lib image not found というエラーが出てしまいました。 やはりcsvファイルは読み込めていないようです
guest

0

PyInstallerは--onefileオプションを指定したときと、指定していないときで挙動が違います(挙動と言うより、exeファイルのパスが異なります)。どちらを想定していますでしょうか?

大まかには以下URLにも書いているのですが
PyInstallerを使ってみた - Qiita
PyInstallerを使うと、__file__sys.argv[0]sys.prefixの値が変わりますので、適宜上手く使い分ける必要があります(PyInstallerで実行ファイル作成済みかどうかは、hasattr(sys, "frozen")で確認できます)。

PyInstallerのonefileを使っていない場合、Path(sys.argv[0]).parentでexeのフォルダパスを取得できます。
onefileオプションを使っている場合、Path(sys.prefix)でexeのフォルダパスを取得できます(onefileオプションを使った場合、Tempフォルダに一度ファイルを展開してから実行することになるため)。
Pathは事前にfrom pathlib import Pathなどとしてインポート済みであるものとします。

まずは、リソースパスの取得処理を見直されると良いかと思います。

投稿2019/03/12 14:38

TakamiChie

総合スコア59

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

vaitarika

2019/03/18 06:58

回答ありがとうございます。 自分はonefileを使用しないで行なっています。 自分は下記のようなディレクトリ構造でプログラムを書いています。 examファイル |--main.py |--sub.py |--*.csv 内容は、mainスクリプトが、同じディレクトリ内にあるcsvファイルを読み込み動作を行うsubスクリプトをimportして使うという形になっています。 この場合、exeのフォルダパスを取得するPath(sys.argv[0]).parentをsubスクリプトに書いてあげればいいのでしょうか。 Pyinstallerを使用した後は、distファイル内にアプリ化されたものと他の諸々が入っているファイルが出来上がると思うのですが、ここでのexeのフォルダパスとはdistというディレクトリのパスということでしょうか。
TakamiChie

2019/03/22 06:49 編集

> exeのフォルダパスを取得するPath(sys.argv[0]).parentをsubスクリプトに書いてあげればいいのでしょうか。 sys.argv[0]の値はsubで使用してもmainで使用しても変わらないですから、どちらでも良いです(エントリポイントとなるソースファイルの値(PyInstaller利用後はexeのあるフォルダパス)となります)。 どこかでメソッドを定義しておくと良いでしょう。 以下は上記の条件で、親フォルダのPathを取得する例です(すみません、上記では`Path(sys.argv[0]).parent`と書きましたが`Path(sys.argv[0])`の誤りでした)。 ```python def mypath(): import sys return Path(sys.argv[0]) if hasattr(sys, "frozen") else \ Path(__file__).parent ``` > distファイル内にアプリ化されたものと他の諸々が入っているファイルが出来上がると思うのですが、ここでのexeのフォルダパスとはdistというディレクトリのパスということでしょうか。 exeファイルがあるフォルダのパスとなります(初期設定の場合、dist/dist/APPのAPPディレクトリのパス)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問