
pythonのグローバル変数についての質問です。
(1)下記のview_select関数のd_frame変数ですが、その関数内ではd_frameの書き換えは行っていないようなのですが、globalの定義はいるのでしょうか?また、panel変数は書き換えを行っているので、この場合、global d_frameの代わりにglobal panelとしてはいけないのでしょうか?
(2)register関数でのin_entry変数は、この関数内で書き換えは行っていないようなのですが、globalの定義はいるのでしょうか?
(3)pythonのグローバル変数の使い方として、関数定義の前に書かれたグローバル変数と、後に書かれたグローバル変数で何か使い方の違いとかあるのでしょうか?
1 import tkinter as tk
2 from tkinter import ttk
3 from tkinter import messagebox
4 import sqlite3
5
6 books_list = []
7 in_entry = [] # 登録情報入力用のEntry
8 sub_win = None
9 s = ('ISBN', 'タイトル', '著者', '出版社', '発売日',
10 '価格(円)', '画像ファイル')
省略
22 # 一覧の書籍を選択すると呼び出される関数
23 def view_select(event):
24 global img
25 global d_frame
26 slct_items = list_view.selection()
27 s = ('ISBN', 'タイトル', '著者', '出版社', '発売日',
28 '価格(円)')
29 for i in range(len(s)):
30 item_view.item(i, values=(s[i],
31 books_list[int(slct_items[0])][i+1]))
32 try:
33 img = \
34 tk.PhotoImage(file=books_list[int(slct_items[0])][7])
35 except tk.TclError:
36 img = ''
37 panel = tk.Label(d_frame, image=img)
38 panel.grid(row=0, column=1)
39
40 # 登録ボタンをクリックすると呼び出される関数
41 def register():
42 global sub_win
43 global in_entry
44 conn = sqlite3.connect('collection.db')
45 cur = conn.cursor()
46 sql = """INSERT INTO books(isbn,
47 title,
48 author,
49 publisher,
50 release,
51 price,
52 image)
53 VALUES(?, ?, ?, ?, ?, ?, ?)"""
54 ele = []
55 for i in range(len(in_entry)):
56 ele.append(in_entry[i].get())
57 cur.execute(sql, ele)
58 conn.commit()
59 conn.close()
60 messagebox.showinfo('メッセージ', '新規登録しました。')
61 sub_win.destroy()
62 disp()
省略
102 # ウインドウの作成
103 root = tk.Tk()
104 root.geometry('400x300')
105 root.title('蔵書管理アプリ')
106 root.resizable(0, 0)
107 root.grid_rowconfigure(0, weight=1)
108 root.grid_rowconfigure(1, weight=1)
109 root.grid_columnconfigure(0, weight=1)
省略
164 # 詳細部分の作成
165 d_frame = tk.Frame(root)
166 d_frame.grid_rowconfigure(0, weight=1)
167 d_frame.grid_columnconfigure(0, weight=1)
168 d_frame.grid_columnconfigure(1, weight=1)
169 column = ('Item', 'Contents')
170 item_view = ttk.Treeview(d_frame, show='tree',
171 columns=column, height = 6)
172 item_view.column('#0', width=0, stretch='no')
173 item_view.column('Item', anchor='w', width=80)
174 item_view.column('Contents', anchor='w', width=140)
175
176 # 詳細の表示
177 slct_items = list_view.selection()
178 print(slct_items)
179 for i in range(len(s)):
180 item_view.insert(parent='', index='end', iid=i,
181 values=(s[i],
182 books_list[int(slct_items[0])][i+1]))
183 item_view.grid(row=0, column=0)
184 try:
185 img = \
186 tk.PhotoImage(file=books_list[int(slct_items[0])][7])
187 except tk.TclError:
188 img = ''
189 panel = tk.Label(d_frame, image=img)
190 panel.grid(row=0, column=1, sticky=tk.NSEW)
191 c_frame.grid(row=0, column=0)
192 d_frame.grid(row=1, column=0,sticky=tk.NSEW)
193
194 root.mainloop()
No.1ベストアンサー
- 回答日時:
> globalの定義は
定義じゃなくって「宣言」ね。
コード全部見ねぇとなんとも言えないんだけど、一つ言えるのは、Pythonってのは割に「スコープ」はデタラメな言語なのね。
フツー、レキシカルスコープ込みの言語だと(つまり、現行使われてる殆どの言語、だ)、変数xが突然使われた場合には、まず、そのスコープの範囲内、そしてそのスコープの外、そこに無かったらまたその外側、の順番で探しに行くわけ。
言い換えると「グローバル変数」ってのは最後に見つけなアカン変数なんだけど。
一方、Pythonにはそういう「マトモな機構」が実は無い。ハッキリ言っちゃえば設計ミス、って言って良い範疇なんだけど、その「機能の貧弱さ」を フォローする為に、「関数の外」とかで大域変数で定義されてる変数を使う場合はglobal宣言を使わなアカン、って、割にこう、アドホックな解決策になってんのね。
だから、
> 書き換え
書き換えするかしないか、ってのは関係ねぇかな。
単にglobal宣言しとかないと、「だらしない」「設計を失敗してる」Pythonは、その関数内で使われてる変数を「関数内での定義」と思っちゃう、って言うそれだけの話だ。
// JavaScriptの場合
js> let i = 1
1
js> function foo() {
> function bar() {
> function baz() {
> i = 2;
> }
> baz();
> }
> bar();
> }
js> foo()
js> i
2
js>
// 関数fooはローカル関数barを持ってて、その中に関数bazがあって、そこで「関数内でいきなり登場した」変数iに2を代入してる。
// iが何者かわからないので、処理系は「iが何なのか」探しに行く。
// まずは関数baz内のスコープ、次にbar内のスコープ、最後にfoo内のスコープでiを探すが、見つからない。最終的には関数foo外に出てiを発見する。iはグローバル変数だ。
// 結果として、JavaScriptは関数baz内で使われたiはグローバル変数だと判定し、グローバル変数iに2を代入し、実際その通りになる。
// これが「モダンな言語」でのレキシカルスコープの動きで、フツーはこうなる。
# Pythonの場合
i = 1
def foo():
def bar():
def baz():
i = 2
baz()
bar()
>>> foo()
>>> i
1
# Pythonにはマトモなレキシカルスコーピングの機能がないので、ローカル関数bazで使われた変数iはグローバル変数iとは別物と判断される。
# 結果、このケースの場合、グローバルで定義したiとローカルで定義されたiは全く別物を判断され、グローバルなiを書き換えたい意図の場合は、アドホックなglobal宣言を行わないとならない。
# ハッキリ言って、この辺はPythonの設計の失敗のウチの一つだと思う。
# しかも「参照は可能」なのでスコーピングの対称性が崩れている。
s = "Hello, World"
def foo():
def bar():
def baz():
print(f"{s}")
baz()
bar()
>>> foo()
Hello, World
# 結果、グローバル変数を「参照」する場合は、混乱を防ぐ為、global宣言を付けてた方が良いだろう。
No.2
- 回答日時:
書き換えてなくても 関数外をアクセスするなら
global や nonlocal を付けた方が親切でしょうね。
うっかり初期化してスコープがローカルにジャンプ
したのに気づかず、悩むのをのを防げるし。
ソースにインデント無いので判断が難しいけど
panel は単なる一時変数で良い気がします。
(3)は意味が取りずらいな。
どちらもグローバル変数が作られるという意味では
同じかな。例えば 関数内で
global a
a = 1
とすると、関数外に a の宣言が無くてもグローバル変数が
作られます。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- その他(プログラミング・Web制作) pythonで、tkinterとpillowの組み合わせ 2 2022/08/16 17:42
- その他(パソコン・スマホ・電化製品) pthonのframeに演算結果(数値)を表示したい 1 2023/06/05 22:08
- Perl RSSにdiv,ul classを付けたいのですがどのようにつけるのかわからないです 2 2022/03/28 01:53
- HTML・CSS CSSのホバーエフェクト 1 2023/06/19 06:53
- その他(プログラミング・Web制作) python OpenPyXLを使って出力結果をエクセルに書き込み 2 2022/06/04 19:46
- その他(プログラミング・Web制作) 物理の斜方投射で目盛りに数値を入れたい 2 2023/05/27 06:32
- その他(コンピューター・テクノロジー) Pythonの np.indicesに関する質問です。 2 2023/02/07 08:19
- Excel(エクセル) エクセル 値をコピペした時に、条件付き書式で塗られた背景色もペーストさせる 2 2023/04/05 17:21
- その他(プログラミング・Web制作) Pythonによる物理の斜方投射の位置座標表示について 2 2023/06/05 12:46
- Visual Basic(VBA) エクセル VBA 難しいです 1 2023/02/21 15:39
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
vba クリップボードクリアにつ...
-
数学、プログラミング、物理、...
-
画像生成AIのプロンプトの作り...
-
Python... 環境設定 初心者です...
-
OS入ってる機器のソフト・アプ...
-
pip --versionがエラーになる
-
パイソンのソースコードをChatG...
-
pythonの実行に関する質問
-
Python 3.12.2 か一番最新のパ...
-
CSVファイルの複数行削除
-
Webサイト内に埋め込んだmp4動...
-
ExcelVBAでFormulaR1C1を列範囲...
-
Pythonのエラーメッセージをコ...
-
ネットワークフォルダの中身を...
-
Pythonで仮想通貨の自動売買が...
-
AIの登場でプログラマーたちが...
-
Google ColaboでGUI作成
-
Pythonについて。
-
HTMLソースが表示のページのも...
-
MOVEコマンドでサブフォルダー...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
vba クリップボードクリアにつ...
-
CSVファイルの複数行削除
-
OS入ってる機器のソフト・アプ...
-
Python 3.12.2 か一番最新のパ...
-
pythonの実行に関する質問
-
パイソンのソースコードをChatG...
-
画像生成AIのプロンプトの作り...
-
数学、プログラミング、物理、...
-
pip --versionがエラーになる
-
Google ColaboでGUI作成
-
Python... 環境設定 初心者です...
-
HTMLソースが表示のページのも...
-
ネットワークフォルダの中身を...
-
MOVEコマンドでサブフォルダー...
-
google Colabでmatplotlibの描...
-
VBAでパワーシェルを実行したい...
-
Pythonでの文字列からfloatへの...
-
Webサイト内に埋め込んだmp4動...
-
初心者powershellのPS1ファイル...
-
pythonについて(初心者です)
おすすめ情報