global文について

今までそういったケースがなかったので気づいていなかったのですが、Pythonは型を指定せずに変数をいきなり登場させられるという仕組み上、関数内からグローバル変数に代入を行うには明示的な指示が必要です。

a = 0

def f():
  a = 5    #このaはローカル変数
  print a  #これも

f()        #5
print a    #0

グローバル変数であることを指示するにはglobal文を使います。

a = 0

def f2():
  global a
  a = 5    #このaはグローバル変数
  print a

f2()       #5
print a    #5

2つ以上の変数をまとめてグローバルとすることも可能です。

a = 0
b = 3

def f3():
  global a,b
  a = 5    #このaはグローバル変数
  b = 7    #このbもグローバル変数
  print a + b

f3()          #12
print a + b   #12

注意点があり、global文でグローバル変数であると指示する名前は同じコードブロック内で先にローカル変数として使ってはいけません。一つの関数内で同じ名前のローカル変数とグローバル変数があってはいけないということですね。

#まちがい
def f4():
  a = 5     #ローカル変数としてaを使った後
  print a
  
  global a  #グローバルのaは扱えない
  a = 10
  print a

f4()

print a

ところがこれ実行してみると"SyntaxWarning: name 'a' is assigned to before global declaration"と表示されるもののコードは最後まで実行され結果は

5
10
10

と期待通りの内容になってるんですよね(^_^;)
コードの実行を中断するほどの致命的なまちがいではないということなのでしょうか。
次のように書くと仕組みがちょっと分かる気がします。

a = 0

def f5():
  a = 5     #ローカル変数としてaを使った後
  print a
  
  global a  #グローバルだよ、と宣言

f5()

print a

結果は

SyntaxWarning: name 'a' is assigned to before global declaration
5
5

となりglobal文の後に何もしていないのにグローバル変数が書き変わっています。どうもglobal文はどこに書いていてもブロックの先頭に書かれているのと同じ扱いとなるようです。Javascriptのvarみたいな感じ(働きは真逆ですが)なのかもしれません。だったら別に「間違い」にしなくてもいいような気もするのですがコードが複雑で読みにくくなるのを防ぐ意図で警告にしているのかもしれませんね。