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

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

新規登録して質問してみよう
ただいま回答率
85.35%
コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

Python

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

Q&A

解決済

3回答

2759閲覧

Pythonのdefについて

sashi

総合スコア1

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

Python

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

0グッド

1クリップ

投稿2020/10/30 17:42

前提・実現したいこと

ここに質問の内容を詳しく書いてください。
Pythonのdefについて質問があります。

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

以下のコードを実行すると A: init B: nonlocal C: nonlocal D: global となるのですが、何故A: local B: nonlocal C: global D: globalとならないのかわかりません。 お手数ですがどなたか教えていただけると助かります。

該当のソースコード

def scope(): loc = "init" def do_local(): loc = "local" def do_nonlocal(): nonlocal loc loc = "nonlocal" def do_global(): global loc loc = "global" do_local() print("A:", loc) do_nonlocal() print("B:", loc) do_global() print("C:", loc) scope() print("D:", loc)

試したこと

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

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

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

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

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

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

guest

回答3

0

Python

1def scope(): 2 loc = "init" # scope's loc bind "init" 3 def do_local(): 4 loc = "local" # do_local's loc bind "local" 5 def do_nonlocal(): 6 nonlocal loc # loc is scope's loc 7 loc = "nonlocal" # scope's loc bind "nonlocal" 8 def do_global(): 9 global loc # loc is global's loc 10 loc = "global" # global's loc bind "global" 11 12 do_local() # do_local's loc bind "local" 13 print("A:", loc) # scope's loc binding "init" 14 do_nonlocal() # scope's loc bind "nonlocal" 15 print("B:", loc) # scope's loc binding "nonlocal" 16 do_global() # global's loc bind "global" 17 print("C:", loc) # scope's loc binding "nonlocal" 18 19scope() 20print("D:", loc) # global's loc binding "global" 21

補足事項として今回のコードのようにローカルなスコープ内でも global 宣言して global 変数を定義可能です。
(Python では変数への代入が変数の定義です)
気を付けることとして、変数を参照するだけの場合は外側のスコープの変数になる点があります。
気を付けることとして、関数内のスコープで global, nonlocal の宣言がなく、変数とオブジェクトの束縛関係を更新しない場合は外側のスコープの変数になる点があります。

Python

1loc = "foo" 2def scope(): 3 print("E:", loc) # loc is global's loc 4 def do_local(): 5 print("F:", loc) # loc is global's loc 6 do_local() 7 8scope() 9# E: foo 10# F: foo

Python

1lst = [0, 1, 2] 2def scope(): 3 print("G:", lst) # lst is global's loc 4 def do_local(): 5 lst[1] = 4 # lst is global's loc lst 変数の束縛関係は更新されない 6 print("H:", lst) # lst is global's loc 7 do_local() 8 lst[0] = 3 # lst is global's loc lst 変数の束縛関係は更新されない 9 print("I:", lst) # lst is global's loc 10 11scope() 12# G: [0, 1, 2] 13# H: [0, 4, 2] 14# I: [3, 4, 2]

投稿2020/10/31 01:16

編集2020/10/31 01:52
lehshell

総合スコア1156

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

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

0

python

1loc="" #1 2def scope(): 3 loc = "init" #2 4 def do_local(): 5 loc = "local" #3 6 def do_nonlocal(): 7 nonlocal loc #<<2 8 loc = "nonlocal" 9 def do_global(): 10 global loc 11 loc = "global" #<<1 12 13 do_local() 14 print("A:", loc) #<<2 15 do_nonlocal() 16 print("B:", loc) #<<2 17 do_global() 18 print("C:", loc) #<<2 19 20scope() 21print("D:", loc) #<<1

3つのlocが存在してるわけで、こう書いとけば理解できるんじゃないかと

投稿2020/10/30 23:30

y_waiwai

総合スコア88042

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

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

0

ベストアンサー

AとCだけ疑問とのことですので、その点を回答します。

  • Aは、loc = "init"のスコープはdef scope()で、loc = "local"のスコープはdef do_local()なので、print("A:", loc)のスコープであるinitになります。
  • Cは、loc = "global"のスコープはdef scope()の外側であるglobalなので、print("C:", loc)のスコープが優先されて、def scope()のスコープでのlocの最新値であるnonlocalになります。

3つのスコープのlocが登場しますので、それを明確に区別したソースにしてみました。これで、どの時点でどの変数を参照や更新しているか、わかるかと思います。

Python

1def scope(): 2 loc_scope = "init" 3 def do_local(): 4 loc_do_local = "local" 5 def do_nonlocal(): 6 nonlocal loc_scope # do_nonlocal()の外のスコープ(すなわちscope())の変数を参照 7 loc_scope = "nonlocal" 8 def do_global(): 9 global loc_global # globalスコープの変数を参照 10 loc_global = "global" 11 12 do_local() 13 print("A:", loc_scope) 14 do_nonlocal() 15 print("B:", loc_scope) 16 do_global() 17 print("C:", loc_scope) 18 19scope() 20print("D:", loc_global)

投稿2020/10/30 22:46

toast-uz

総合スコア3266

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問