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

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

新規登録して質問してみよう
ただいま回答率
85.51%
Python 3.x

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

Python

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

Q&A

解決済

3回答

908閲覧

関数内のローカル変数を他の関数内で使用したい

hani3044

総合スコア2

Python 3.x

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

Python

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

0グッド

1クリップ

投稿2023/03/26 04:59

前提

Windowsを使っている初心者です。Pythonで実行したいと考えています。
returnや関数の理解がまだできていないのかと思います。

実現したいこと

GUIで実装を考えています。内容は下記の通りです。
① フォルダを選択
② 該当フォルダの中にあるpngファイルをリスト化
③ そのリストを「rename.csv」に書き込んで開く

「フォルダ選択」ボタンで①を、「リストを作成」ボタンで②、③を実行したいです。
グローバル変数はあまり使いたくないです。

発生している問題・エラーメッセージ

「リスト作成」list_create()にdef select_folder()で選んだフォルダのパス(folder_path)を渡す方法が知りたいです。
今回はこの処理だけですが、ファイル移動等他の処理にもこのパスを使うことを想定しています。

TypeError: list_create() missing 1 required positional argument: 'folder_path'

該当のソースコード

Python

1################################################################### 2#フォルダ選択 3################################################################### 4 5# フォルダ選択ダイアログ表示 6def select_folder(): 7 folder_path = filedialog.askdirectory() 8 return folder_path 9 10 11################################################################### 12#リスト作成 13################################################################### 14 15def list_create(folder_path): 16 path = folder_path + '/*.png' 17 filelist = glob.glob(path, recursive=True) 18 filelist = [os.path.splitext(os.path.basename(f))[0] for f in filelist] 19 20 # リスト内の重複を削除 21 filelist = (list(set(filelist))) 22 23 filelist.sort() 24 filelist.insert(0, '変更前ファイル名') 25 filelist2 = np.array(filelist).reshape(-1, 1).tolist() 26 27 # rename.csvにデータを書き込み 28 with open('rename.csv', 'w' , newline='') as f: 29 writer = csv.writer(f) 30 writer.writerows(filelist2) 31 32 # rename.csvを開く 33 os.startfile('rename.csv') 34 35# 画面作成 36window = tkinter.Tk() 37window.geometry('250x150') 38window.title('ファイルリスト作成') 39 40# ボタン作成[リンク内容](url) 41button0 = tk.Button(window, text='フォルダ選択', command=select_folder) 42button1 = tk.Button(window, text='リストを作成', command=list_create) 43 44# ボタン表示 45button0.place(x=10, y=10) 46button1.place(x=10, y=50) 47 48button1.bind("<Button-1>",list_create) 49 50# 画面表示 51window.mainloop() 52

試したこと

list_create関数の中でselect_folder関数を再実行してそれを folder_pathに繋いだのですが、当然ですが「リスト作成」ボタンで再度フォルダ選択画面が出てしまいます。

def list_create(): folder_path = select_folder() path = folder_path + '/*.png'

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

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

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

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

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

guest

回答3

0

回答ついてますが、ちょっとコメント

なるべくグローバル変数を使いたくないということですが、通常のプログラムを作る上では、いい姿勢だと思います。
しかし、そういう構造にするためには、関数が処理結果をグローバル変数の書き換えのような副作用でなく、returnで返すようにする必要があります。

さて、GUIのプログラムは、イベントループ内で、イベントに紐付けられたコールバックが起動されることで動作しますが、大抵の場合、呼び出されたコールバックの返り値は捨てられてしまうので利用する方法がありません。

ということで、GUIのプログラムでは、イベントで処理された結果は

  • グローバル変数に格納する
    変数が多くなるような場合は、保持用の辞書などを使って整理するなど
  • ウィジェットの値を読む
    削除せず見えなくするだけなどで利用
  • ファイルやDBに保存

などの方法を採ることが多いです。

投稿2023/03/26 09:04

TakaiY

総合スコア12651

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

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

hani3044

2023/03/26 10:20

ありがとうございます! こちらの方のやり方も今少しずつ試しています。 できれば全部のやり方一旦理解して勉強してみたく思います。
guest

0

ローカル変数ってのは、その定義した関数内でしか使えません
なので、グローバル変数を使う必要があります

投稿2023/03/26 05:02

y_waiwai

総合スコア87715

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

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

hani3044

2023/03/26 10:56

ありがとうございます。 グローバル変数について、他の方のコードと組み合わせる可能性があったので避けていたのですが場合によっては考えないといけないのですね。 勉強がんばります。
guest

0

ベストアンサー

tkinter.StringVar()(ウィジェット変数)を使う方法もあります。

python

1# フォルダ選択ダイアログ表示 2def select_folder(folder): 3 folder_path = filedialog.askdirectory() 4 folder.set(folder_path) 5 6def list_create(folder_path): 7 : 8 9 10# ボタン作成[リンク内容](url) 11folder = tk.StringVar() 12button0 = tk.Button(window, text='フォルダ選択', command=lambda: select_folder(folder)) 13button1 = tk.Button(window, text='リストを作成', command=lambda: list_create(folder.get())) 14 15# ボタン表示 16button0.place(x=10, y=10) 17button1.place(x=10, y=50) 18 19#button1.bind("<Button-1>",list_create) 20 21# 画面表示 22window.mainloop()

投稿2023/03/26 06:36

melian

総合スコア19600

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

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

hani3044

2023/03/26 09:29

ありがとうございます。 tkinter.StringVar()(ウィジェット変数)を使う方法を知らなかったため、いただいたコードを入れていろいろ検索してほかの処理も組み合わせてみたところ無事に思い通りの処理ができました。 もう少し調べてみます。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.51%

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

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

質問する

関連した質問