-1

何らかの理由でtimeit、次の例ではPython-2.7関数がクラッシュします。

a,b = 0,0
timeit a=b                  # ok: 10000000 loops, best of 3: 50.9 ns per loop
timeit if a==a+b: pass      # ok:  1000000 loops, best of 3: 129 ns per loop
timeit a=a+b                # crashes!

Traceback (most recent call last):
UnboundLocalError: local variable 'a' referenced before assignment

どうやら、a(最初の例)に割り当てることができ、(2番目の例)と比較aするa+bことができるので、なぜ3番目の例を実行できないのですか?!?!もちろん、タイミングを合わせているステートメントは、それ自体、完全に健全です...

4

1 に答える 1

3

timeitは実際には関数ですが、一部のPythonインタープリターでは、のようなステートメントの構文で使用できますが、IPython実際には関数です。

したがって、a==a+b実際にはとをグローバル変数と見なしabグローバル変数とをフェッチできるため、エラーは発生しませab

しかし、 Pythonはローカル変数とa=a+b見なし、まだグローバルであるため、エラーが発生します。これは、Pythonが関数内の割り当てを確認するとすぐに、それをローカル変数と見なすためです。ab

これは次と同等です。

In [7]: def func1():
    a==a+b
   ...:     

In [8]: def func():
    a=a+b
   ...:     

In [9]: dis.dis(func1)
  2           0 LOAD_GLOBAL              0 (a)
              3 LOAD_GLOBAL              0 (a)
              6 LOAD_GLOBAL              1 (b)
              9 BINARY_ADD          
             10 COMPARE_OP               2 (==)
             13 POP_TOP             
             14 LOAD_CONST               0 (None)
             17 RETURN_VALUE        

In [10]: dis.dis(func)
  2           0 LOAD_FAST                0 (a)   # but there's nothing to load, so Error
              3 LOAD_GLOBAL              0 (b)
              6 BINARY_ADD          
              7 STORE_FAST               0 (a)
             10 LOAD_CONST               0 (None)
             13 RETURN_VALUE        


In [11]: func()     #same error as yours
---------------------------------------------------------------------------
UnboundLocalError                         Traceback (most recent call last)

UnboundLocalError: local variable 'a' referenced before assignment
于 2012-12-20T14:32:35.327 に答える