2013-04-17 53 views
1

我有一個功能和燒瓶路線設置。但是,當我去「simplepage」,我得到一個錯誤「NameError:全球名稱」aaa'未定義「。爲什麼沒有任何對象被傳遞給testfun?這是由於app.route裝飾器,或由於瓶?我可以將所有對象傳遞給testfun嗎?我的實際代碼複雜得多,需要傳遞更多的對象,但是這個簡化的場景是爲了說明我的問題而創建的。對象沒有被傳遞到燒瓶路線中的功能

def testfun(): 
    b=aaa 

@app.route("/simplepage/", methods=['GET']) 
def simplepage(): 
    aaa=1 
    testfun() 
    return flask.render_template('page.html') 
+0

爲什麼不能通過'aaa'作爲參數傳遞給'testfun()'(即'testfun(AAA)') – John

+0

很好,在我的實際應用中還有很多更對象通過,我也有重新導入很多模塊,併爲多個功能執行此操作。我寧願避免所有這些,並使代碼更簡潔,更易於維護。我不認爲我通常有這個問題。 – user1748155

+0

經過一些研究,我確信這是[範圍](http://stackoverflow.com/a/292502/322909)問題... – John

回答

1

基本上所發生的事情是這樣的

def t(): 
    print aaa 

def s(): 
    aaa = "hi" 
    t() 

s() 

Python將aaa先在局部範圍內,那麼在任何包裝功能部件範圍,然後在全球範圍,最後在建宏。由於s函數範圍不是任何這些東西python拋出一個未定義的錯誤,因爲它找不到aaa

一種解決方案是將aaa聲明爲全局。

def t(): 
    print aaa 

def s(): 
    global aaa 
    aaa = "hi" 
    t() 

s() 
+0

我想混淆的是,一個對象必須定義在最頂層函數被調用或定義的位置,但是任何子函數只會從已定義的級別獲取傳遞給它們的對象,而不是它們被調用的位置。 – user1748155

+0

以下不工作: – user1748155

+0

DEF S(): DEF噸(): 打印AAA AAA = 「喜」 噸() ()的 – user1748155

3

這是由於Python's scoping rules(如@johnthexiii指出的) - testfun->aaa勢必會在全球範圍內,因爲沒有名爲aaa變量testfun內部的任何聲明,也沒有封閉的範圍(即testfun不在另一個函數或類中聲明)。

你想通過aaa作爲參數傳遞給testfun

testfun(aaa) 

如果testfun需要太多PARAMS有幾種方法,你可以幹起來代碼:

  • 使用多功能:如果testfun正在做很多工作,然後將其分解成多個函數,返回數據的中間轉換:

    def start_test(arg1, arg2, arg3): 
        # do stuff with args 
        return result_stage_1 
    
    def continue_test(arg3, arg4, arg5): 
        # do stuff with args 
        return result_stage_2 
    
    def finalize_test(arg7, arg8): 
        # do stuff with args 
        return real_result 
    
  • 使用關鍵字參數:如果需要的參數個數可變和testfun不能被打破了,你可以用關鍵字參數來簡化函數的調用:

    def testfun(arg1=None, arg2=None, arg3=None, arg4=None, 
           arg5=None, arg6=None, arg7=None, arg8=None): 
        # do stuff with args 
    
    # call it as so 
    args = {"arg1": "some args", "arg5": "have defaults"} 
    if complex_condition: 
        args["arg3"] = 17 
    elif another_condition: 
        args["arg7"] = 10 
    
    testfun(**args) 
    
  • 使用類(或閉包)封裝狀態和行爲:如果上述兩種方法都不適合您,那麼您可能需要離開無狀態函數和創建的領域e類或閉包創建函數來保存您的狀態並使您能夠根據需要修改行爲。

相關問題