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

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

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

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

Q&A

3回答

1273閲覧

別のモジュールへ変数を渡す Python

goki_gottan

総合スコア168

Python 3.x

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

0グッド

0クリップ

投稿2022/07/12 02:14

別のモジュールから変数を受ける方法は熟知しているのですが、変数を与える(メイン⇒サブ)でつまづいております。

Main_GUI.py

import sub import PyQt5... class window(QWidget): def __init__(self): def initUI(self): global gg gg="●.png" sub.main() def main_1(): ex = window() ex.show() if __name__ == '__main__': main_1()

sub.py

import sys import tkinter as tk class viewerGUI(tk.Frame): def __init__(self,master=None): super().__init__(master) sys.path.append("Main_GUI ") from Main_GUI import gg print(gg) def main(): global root root=tk.Tk() gui=viewerGUI(master=root) gui.mainloop()

メイン.py(Main_GUI.py)を起動、main_1()が起動。
pyqt5のGUIが起動し、ggの値を取得。global変数化。
サブ.pyのmain()を起動指示。
サブのmian()が起動し、tkinterが起動する前に、メイン帰属のgg変数を見に行く。

こんな感じです。

エラー内容:

ImportError: cannot import name 'gg' from 'Main_GUI' (C:\Users\●t\Main_GUI.py)

となります。他にもいろいろと試してみましたが、ggを取得できません。
変数なしで起動は確認(tkinterとpyqt5の相性は問題なし)
メインからサブへ、クラス関数以下になる変数の場合は取得方法が異なるのでしょうか?

宜しくお願いいたします。

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

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

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

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

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

guest

回答3

0

単にその結果を返す関数を書いておいてそれ呼び出せばいいんでは

投稿2022/07/12 02:39

y_waiwai

総合スコア87747

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

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

0

意図しているのは多分こう。

sys.path.append("Main_GUI ") from Main_GUI import gg

from __main__ import gg

追記

pyhton Main_GUI.py

として実行した場合、Main_GUI.py がロードされてできたモジュールには、 Main_GUI という名前ではなく、__main__という名前が付けられています。 > https://docs.python.org/ja/3.9/library/__main__.html

python

1if __name__ == '__main__':

というコードをイディオムとして覚えてしまっているのかもしれませんが、ここでチェックしているのは上記の動作です。
pyhton Main_GUI.pyと実行された時は自身のモジュールの名前は__main__になっています。
Pythonコード中でimport Main_GUIと実行されてロードされた時は自身のモジュールの名前はMain_GUIになっています。
それをif文でチェックしているのです。

だからpyhton Main_GUI.pyと実行された時、main_1が実行され、window.initUIが実行され、その中でグローバル変数ggが作られるのです。
そのグローバル変数ggを他からインポートするには

python

1 from __main__ import gg

とする必要があります。

Pythonコマンドの引数に指定した実行ファイルを、他の場所で

python

1 from Main_GUI import gg

のようにファイル名でインポートしてしまうと、__main__としてロードされているものとは別の(Main_GUIという名前の)モジュールができてしまいます。
そこにはggというグローバル変数はないのでエラーになります。


import 文はそれが実行された場所の名前空間に名前を束縛します。
関数実行中、関数内でimport文を書いたら、その文が作る変数はローカル変数になります。

グローバルなところで

Main_GUI.py

1import sub

sub.py

1from __main__ import gg

と書くと循環インポートになります。今回のケースはこれはうまくいきません。
関数内部でローカルインポートするのが、うまく動かす方法です。その点では、もとのコードのインポート位置はよいと思います。(ggが__init__の中のローカル変数になっていますが、それが質問者さんの意図通りなのかは推し量ることは出来ませんが)

一般にはグローバルな箇所での循環インポートは、動くかどうかがインポートする順番に左右されることが多いので、パッケージ-サブパッケージ間の循環インポート以外には書くべきではないです。


これはこれとしてy_waiwai さんの解答の方が正答です。

投稿2022/07/12 03:19

編集2022/07/14 06:23
quickquip

総合スコア11038

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

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

quickquip

2022/07/12 04:03 編集

動くであろうコードに低評価付けるなら理由を書いて欲しいです。おかしいコードだとは思わないのですが。 (「説明が不足」「初心者に教えるべきでないコード」だという話なら、それは確かにそうなのでそのままでよいです)
goki_gottan

2022/07/14 06:08

ご回答くださり、ありがとうございます。また親切に説明くださり、ありがとうござした。 確認させてください。
guest

0

そのパターンは不可能ですね。変数を外部ファイルからインポートできるようにする場合はMain_GUI.pyのimport文の下辺りにgg="●.png"を移動してください。

投稿2022/07/12 02:29

usekay

総合スコア395

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

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

usekay

2022/07/12 02:31

説明が足りませんでしたね。Pythonでインポートできるのはスコープがモジュール=そのファイル内からならどこからでも参照できる変数になります。
goki_gottan

2022/07/12 02:34

メインの初期のimport 文以下に書くということですよね? ご回答ありがとうございます。変数ggは、メインで別の関数クラス内で算出されており、外に出すことは難しいです。 その場合、ggとのやり取りはメインですべてすべきという事でしょうか?
usekay

2022/07/12 03:33

Main_GUI.pyが常に最初に実行されるようなのでそんなに難しいようには思えませんがどのような点を懸念されていますか。 そもそもこの程度ならスコープをモジュールにせず関数やコンストラクタ経由でパラメータを引き渡したほうが自然だとは思いますが。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問