Python 未传递到flask路由中函数的对象

Python 未传递到flask路由中函数的对象,python,function,flask,decorator,routes,Python,Function,Flask,Decorator,Routes,我有一个功能和一个烧瓶路径设置。但是,当我转到“simplepage”时,我得到一个错误“NameError:未定义全局名称'aaa'。为什么没有任何对象被传递给testfun?这是因为app.route decorator,还是因为flask?我可以将所有对象传递给testfun吗?我的实际代码要复杂得多,需要传递更多的对象,但创建这个简化的场景是为了说明我的问题 def testfun(): b=aaa @app.route("/simplepage/", methods=['GE

我有一个功能和一个烧瓶路径设置。但是,当我转到“simplepage”时,我得到一个错误“NameError:未定义全局名称'aaa'。为什么没有任何对象被传递给testfun?这是因为app.route decorator,还是因为flask?我可以将所有对象传递给testfun吗?我的实际代码要复杂得多,需要传递更多的对象,但创建这个简化的场景是为了说明我的问题

def testfun():
    b=aaa

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

基本上是这样的

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()

基本上是这样的

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()
这是由于(正如@johnthexiii所指出的)
testfun->aaa
绑定到全局范围,因为在
testfun
中没有声明名为
aaa
的变量,也没有封闭范围(即
testfun
未在另一个函数或类中声明)

您需要将
aaa
作为参数传递给
testfun

testfun(aaa)
如果
testfun
需要太多参数,有几种方法可以使代码干涸:

  • 使用多个函数:如果
    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)
    
  • 用类(或闭包)封装状态和行为:如果上述两种方法都不适用于您,那么您可能需要离开无状态函数的领域,创建类或闭包创建函数以保留您的状态,并允许您根据需要修改行为

这是因为(正如@johnthexiii指出的)testfun->aaa绑定到全局范围,因为在
testfun
的任何地方都没有声明名为
aaa
的变量,也没有封闭范围(即,
testfun
没有在另一个函数或类中声明)

您需要将
aaa
作为参数传递给
testfun

testfun(aaa)
如果
testfun
需要太多参数,有几种方法可以使代码干涸:

  • 使用多个函数:如果
    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)
    
  • 用类(或闭包)封装状态和行为:如果上述两种方法都不适用于您,那么您可能需要离开无状态函数的领域,创建类或闭包创建函数以保留您的状态,并允许您根据需要修改行为


为什么不将
aaa
作为
testfun()
(即
testfun(aaa)
)的参数传递呢?好吧,在我的实际应用程序中,要传递的对象要多得多,我还必须重新导入许多模块,并对多个函数执行此操作。我宁愿避免所有这些,让代码更干净,维护更简单。我想我通常不会有这个问题。经过一点研究,我很确定这是一个问题……为什么不将
aaa
作为
testfun()
(即
testfun(aaa)
)的参数传递给我呢,并对多个函数执行此操作。我宁愿避免所有这些,让代码更干净,维护更简单。我想我通常不会有这个问题。经过一点研究,我很确定这是一个问题……我想混淆的是,必须在调用或定义最顶层函数的位置定义对象,但任何子函数都只能从已定义的位置传递对象,而不是调用它们的位置。def s():def t():打印aaa=“hi”t()s()我想混淆之处在于,必须在调用或定义最顶层函数的位置定义对象,但任何子函数都只能从已定义的位置向它们传递对象,而不是从它们被调用的位置。def s():def t():print aaa=“hi”t()s()