2016-03-19 34 views
3

Burada python2.7 diddling ediyorum:Bir işlevde bir modül kullanıldığında RE-içe aktarma neden bir istisna atar?

istisna atar
import time 

def foo(): 
    print time.time() # EXCEPTION THROWN HERE 
    import time 

...:

UnboundLocalError: local variable 'time' referenced before assignment 

Ben tekrar import kaldırırsanız:

import time 

def foo(): 
    print time.time() # WORKS AS EXPECTED 
    #import time 

.. her şey gerektiği gibi çalışır.

import time 

def foo(): 
    global time 
    print time.time() # WORKS AS EXPECTED 
    import time 

... garip: DEĞİL içerme açısından - Bu fonksiyonun an yürütme başlar gelen, daha sonra almak ilgili bir şey, yerel değişken tablo etkiler işlevi çağrıldığında, bu çok açık .

Bu, bir mühendis, büyük bir yöntemin en üstünde time.time() öğesine bir çağrı eklediğinden, ancak işlevin ortasında (uzun süre gitmiş bir mühendis tarafından içe aktarıldığını görmediğinden) ortaya çıktı. .) Sorunun nasıl çözüleceğine dair rehberlik istemiyorum - bu durum açıkça belli ki (ve bunu yapan kişiyi avlamak için gerekli olan uyuşukluğu da beraberinde getirecektir.)

mekanizma, neden bu şekilde yapılır, ve sistemin hangi bölümlerinin hepsini görebildiğini kontrol edebilirim.

+0

Gerçekten hiç de garip değil, her şey kapsam içine düşüyor, davranış herhangi bir değişken kullanılarak tam olarak aynı olurdu. –

cevap

2

Sorun, import ile ilgili bir sorun yok. Bu sadece küresel ve yerel değişkenler hakkında.

x = 0 

def access(): 
    print(x) 

def shadow(): 
    print(x) 
    x = 1 
Şimdi

işlevlerini sökmeye ve baytkoduna bir göz atalım:

access()

0 LOAD_GLOBAL    0 (print) 
3 LOAD_GLOBAL    1 (x) 
6 CALL_FUNCTION   1 (1 positional, 0 keyword pair) 
9 POP_TOP 
10 LOAD_CONST    0 (None) 
13 RETURN_VALUE 

Sen sembol x global olarak aranır olduğunu görebilirsiniz bu asgari örneğe bakın değişkeni LOAD_GLOBAL 1 (x)

0 LOAD_GLOBAL    0 (print) 
3 LOAD_FAST    0 (x) 
6 CALL_FUNCTION   1 (1 positional, 0 keyword pair) 
9 POP_TOP 

10 LOAD_CONST    1 (1) 
13 STORE_FAST    0 (x) 
16 LOAD_CONST    0 (None) 
19 RETURN_VALUE 
İşlev gövdesindeki x değişkenini yeniden tanımladığınızda, bu bayt kodunu alırız: LOAD_FAST 0 (x). Dolayısıyla, bu noktada tanımlanmamış olsa bile yerel değişken olarak bakılır. x yerel değişkeni tanımlanmadığı için henüz tanımlanmamış UnboundLocalError yerel değişkeni aldık.

Örneğinizde, time modülü, global/local değişkendir.

+1

anahtar içgörü, çalışma zamanında dinamik olmak yerine, global/yerel çözünürlüğün kod oluşturma zamanında yapılmasıdır - evet imho bu garip – jsalter