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

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

ただいまの
回答率

88.64%

lambaで実行した関数の中の内部関数の戻り値を取り出したい。関数の戻り値が正しく代入出来ない。

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 697

Aki1000

score 39

a=QuestionBox("質問箱","temp.txt")
とすると、質問用のメッセージボックスが出て、ボタンが押されたら書かれたテキストを、ファイルに書き込んだ後、そのテキストを戻り値とするコードを作っています。

しかしながら、下記のコードのFlagWright():の処理では、ファイルには正しく書き込まれるのですが、戻り値がnoneとなってしまいます。
どうしたら、正しく戻り値がaに入力されるのでしょうか?

追記
root.mainloop()の後にreturn numと書くと、その値は戻り値としてaに代入される。
def QuestionBoxの中の内部関数としてdef FlagWrightを書いたが、ここでreturn numとやってもdef QuestionBoxの中にしか戻らないみたいです。
関数の中の内部関数の戻り値を取り出したいと、タイトルを変更します。

import tkinter
import os

def QuestionBox (mes, filename="none", x=50, y=50, width=900, height=150, title="Question",
                 workdir="C:\temp\"):
    # Tkクラス生成
    root = tkinter.Tk()
    root.geometry('{}x{}+{}+{}'.format(width, height, x, y))
    root.title(title)
    root.attributes("-topmost", True)
    root.option_add('*font', (u'MS ゴシック', 20))

    # ラベル
    lbl = tkinter.Label(text=mes)
    lbl.place(x=30, y=10)

    # テキストボックス
    # txt = tkinter.Entry(width=7, font="u'MS ゴシック', 20, 'bold'", title="Question")
    txt = tkinter.Entry(width=7)
    txt.option_add('*font', (u'MS ゴシック', 20, 'bold'))


    txt.place(x=1150, y=15)
    txt.pack(padx=5, pady=5, anchor=tkinter.SE)
    # txt.insert(tkinter.END, "3")

    def FlagWright():
        num = txt.get()
        if filename != "none":
            pathstring = os.path.join(workdir,filename)
            with open(pathstring, 'w', encoding='utf-8') as file:
                file.write(num)
        root.quit()
        return num

    # button1 = tkinter.Button(root, text='決定', command=lambda: make_cmd(root),
    button1 = tkinter.Button(root, text='決定', width=10, height=2, command=lambda :FlagWright())
    button1.pack(side=tkinter.BOTTOM, padx=5, pady=5, anchor=tkinter.SE)

    root.mainloop()
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

今回 return を返すべきなのは FlagWright()関数ではなくて、 QuestionBox()関数なので

QuestionBox() を

def QuestionBox():
    result = None
    ...
    return result


のように実装し、FlagWright() ではこの result を

def FlagWright():
    nonlocal result
    ...
    result = num
    root.quit()

のようにして書き換えると良いかと思います

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/11/16 18:06

    ありがとうございます。
    ところで、いろいろなところでグローバル変数さけるべし、と言う事が書かれているのですが………このnonlocalというのは大丈夫なんでしょうか………
    働きを見るにグローバル変数の一種?

    キャンセル

  • 2018/11/16 18:46

    nonlocal も用途としては global変数のようなものですが、global はファイル全体からアクセスできるのに対して、nonlocalはネストされた関数から親のローカル変数にアクセスするのに使用します。
    global変数が悪とされるのは「可読性が損なわれる」「誰が何処からどのタイミングで書き換えたのかが分かり難く保守性が低下する」ことかと思います。
    nonlocalは書き換えられる範囲も限定的なので、関数を短く簡潔に書けるのであれば可読性も落ちることはないので、それほど悪い選択肢ではないと個人的には思います。

    キャンセル

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

  • ただいまの回答率 88.64%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • トップ
  • Pythonに関する質問
  • lambaで実行した関数の中の内部関数の戻り値を取り出したい。関数の戻り値が正しく代入出来ない。