2013-07-11 53 views
0

嗨即時做測試udacity當然,我不明白爲什麼即時通訊全球變得這個問題。「兒子」功能不能看到「父親」功能當地人

事情是有一些我想測試隊列的實現。爲了做到這一點,我使用斷言對發佈條件[empty,full,enqueue,dequeue]進行了包裝,然後繼續對包含函數的結構進行隨機測試,以使測試自動化。

對於斷言,我需要跟蹤隊列和實際項目(elts)的最大項目(大小),所以我將它們定義爲函數test()中的本地值。

內部測試()我定義的包裝和包裝我使用大小和elts。

我不明白的是如果我在封裝定義中使elt全局,那麼我得到一個NameError全局名稱'elts'沒有在封裝器中定義但是如果我不把它聲明爲全局的封裝,那麼我得到在爲其分配值之前訪問elts的UnboundLocalError。

我不明白爲什麼在「父」函數的主體中聲明的「子」函數不能看到父親的局部變量並使用它。

下面是代碼

from queue_test import * 
import random 
import sys 

def test(): 
    # Globals 
    iters=100 
    max_int=sys.maxint 
    min_int=1 
    elts=0 
    size=0 

    #Queue wrappers 
    # Wrapp the queue methods to include the assertions for automated testing 
    def run_empty(): 
     temp=q.empty() 
     if elts==0: 
      assert temp==True 
     else: 
      assert temp==False 
     return temp 
    def run_full(): 
     temp=q.full() 
     if elts==size: 
      assert temp==True 
     else: 
      assert temp==False 
     return temp 
    def run_enqueue(val): 
     temp=q.enqueue(val) 
     if isinstance(val,int) and elts<size: 
      elts+=1 
      assert temp==True 
     else: 
      assert temp==False 
     return temp 
    def run_dequeue(): 
     temp=q.dequeue() 
     if elts>0: 
      elts-=1 
      assert temp!=None and isinstance(temp,int) 
     else: 
      assert temp==None 
     return temp 

    # Random testing stuff 
    def get_int(): # Return a random valid integer 
     return random.randint(min_int,max_int) 
    def get_command(): #Return a random valid command (string) 
     return random.choice(["empty","full","enqueue","dequeue"]) 
    def run_random_command(): # Execute a random command 
     c=get_command() 
     if c=="empty": 
      run_empty() 
     elif c=="full": 
      run_full() 
     elif c=="enqueue": 
      run_enqueue(get_int()) 
     elif c=="dequeue": 
      run_dequeue() 
     else: 
      raise Exception("Error run command invalid command") 
    def test_this(ncommands=100): # Randomly test a queue with ncommands commands 
     run_empty() 
     testi=get_int() 
     run_enqueue(testi) 
     testi2=run_dequeue() 
     assert testi == testi2 
     for c in range(ncommands): 
      run_random_command() 

    #Test Code: Do it random tests each one with a diferent random queue 
    for it in range(iters): 
     size=get_int() 
     elts=0 
     q=Queue(size) 
     test_this() 

回答

3

如果在函數內分配給一個變量,Python的自動使得本地。您需要在子功能中明確標記爲global。 (在Python 3中,你可以使用nonlocal。)

但是,我不禁想着你真的應該在這裏使用一個類。

+0

+1說這應該是一個對象。他在這裏也沒有實際定義全局變量,只是'test()'函數範圍內的值。其他的一切都是封閉的,所以當他試圖改變其中任何一個裏面的'elts'的值時,它們就會炸燬。 –

+0

是的,多虧了帥哥,我明白了;)都非常有幫助。 – Torrezno