我有一个功能和一个烧瓶路线设置。但是,当我转到“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 :(得分:3)
这是由于Python's scoping rules(正如@johnthexiii指出的那样) - testfun->aaa
绑定到全局范围,因为在{{1}内部没有声明名为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
用类(或闭包)封装状态和行为:如果上述两种方法都不适合您,那么您可能需要离开无状态函数领域并创建类或闭包 - 创建保存状态的函数,并使您能够根据需要修改行为。
答案 1 :(得分:1)
基本上正在发生的是这个
def t():
print aaa
def s():
aaa = "hi"
t()
s()
Python首先在本地范围内查找aaa
,然后在任何包装函数范围中查找s
,然后在全局中查找,最后在内置函数中查找aaa
。由于aaa
函数作用域不是任何一种,python会抛出一个未定义的错误,因为它找不到def t():
print aaa
def s():
global aaa
aaa = "hi"
t()
s()
。
一种解决方案是将{{1}}声明为全球。
{{1}}