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')
4

2 回答 2

3

这是由于Python 的作用域规则(正如@johnthexiii 指出的那样) -testfun->aaa绑定到全局作用域,因为在其中的任何aaa地方都没有声明命名的变量testfun,也没有封闭作用域(即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)
    
  • 用类(或闭包)封装状态和行为:如果上述方法都不适合您,那么您可能需要离开无状态函数的领域并创建类或创建闭包的函数来保留您的状态并使您能够将行为修改为需要。

于 2013-04-17T04:11:59.197 回答
1

基本上发生的事情是这样的

def t():
    print aaa 

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

s()

Pythonaaa首先在本地范围内查找,然后在任何包装函数范围内查找,然后在全局范围内查找,最后在内置函数中查找。由于s函数作用域不是任何这些东西,python 会抛出一个未定义的错误,因为它找不到aaa.

一种解决方案是声明aaa为全局。

def t():
    print aaa

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

s()
于 2013-04-17T02:55:13.200 回答