Skip to content

Instantly share code, notes, and snippets.

@civic
Created September 19, 2012 02:55
Show Gist options
  • Save civic/3747391 to your computer and use it in GitHub Desktop.
Save civic/3747391 to your computer and use it in GitHub Desktop.

https://gist.github.com/3746850 result.

source code

def main():
  x1=1
  x2=1

  def func1():
    y1=x1+10        # x1 is in "enclosing function's scope"
    print 'func1', x1, y1

  def func2():
    y2=x2+10        # x2 is in local scope. x2 is not set value.
    x2=2            # x2 is defined at local scope 
    print 'func2', x2, y2
 
  func1()
  func2()

main()

output

func1 1 11
UnboundLocalError: local variable 'x2' referenced before assignment
@civic
Copy link
Author

civic commented Sep 19, 2012

func1での変数x1は、関数内での代入がないのでローカルスコープではなく、外側の関数スコープ(Enclosing Function's Scope)になる。
つまりmain関数でのローカル変数x1が参照できる。

func2での変数x2は、関数内での代入があるのでローカルスコープになる。(代入するコード順序に関係ない)
しかしながら、x2はまだ値が未設定のまま参照されているので(y2=x2+10)、UnboundLocalErrorになる。

ネストされた関数内で、外側の関数スコープの値を変更することはPython2ではできない。参照だけならばできる。
(Javaのメソッド内匿名インナークラスで、外側のメソッド内ローカル変数はfinal定義しないと参照できないのに似ている。)

\Python3ではnonlocal宣言ができて、よりカオスになりました/

def func2():
   nonlocal x2          #enclosing function's scopeのx2だよ宣言
   y2 = x2+10
   x2=2
   print('func2', x2, y2)  #printも関数になった

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment