Python Flask-递归函数调用时忽略的默认参数(单独调用之间累积的值)
我在并行调用FlaskAPI时遇到了一个问题(只有2个实例出现了这个问题)。在我的完整代码中,我从表中请求数据,然后创建一个json树,该树将显示在前端。我注意到我的树看起来很奇怪,第一棵树还行,但是第二棵树包含了第一棵树的所有节点,然后只包含了第二棵树的节点) 我调用一个递归函数来构建我的树,它看起来像是两个并行执行之间“共享”了一些变量(这对我来说没有意义,因为我调用了一个对象的两个不同实例的方法) 我创建了下面的示例,它复制了我的问题 结果变量应该是一个列表,其中包含每个递归执行的数字(因此对于5,我希望是[1 2 3 4 5] 但是,当我多次执行代码(通过执行刷新)时,我可以看到我的结果列表变得更大了(因此在两次刷新之后,我的列表是[1 2 3…75](递归只能执行5到15次) 我没有在递归方法的初始调用中指定numbers参数:Python Flask-递归函数调用时忽略的默认参数(单独调用之间累积的值),python,Python,我在并行调用FlaskAPI时遇到了一个问题(只有2个实例出现了这个问题)。在我的完整代码中,我从表中请求数据,然后创建一个json树,该树将显示在前端。我注意到我的树看起来很奇怪,第一棵树还行,但是第二棵树包含了第一棵树的所有节点,然后只包含了第二棵树的节点) 我调用一个递归函数来构建我的树,它看起来像是两个并行执行之间“共享”了一些变量(这对我来说没有意义,因为我调用了一个对象的两个不同实例的方法) 我创建了下面的示例,它复制了我的问题 结果变量应该是一个列表,其中包含每个递归执行的数字(因
result = test_recursive.recursive_function(random.randint(5, 15))
正如我所期望的,它将初始化为默认值中指定的空数组:
def recursive_function(self, iterations, numbers=[]):
数字列表似乎没有被重新初始化为空数组,但它保留了上次执行的值。我有点困惑于这是怎么可能的
我可以通过显式指定numbers参数来解决问题
结果=测试递归递归函数(random.randint(5,15),[])
然而,我对这个解决方案并不满意,因为在我真正的递归函数中,我有更多带有默认值的参数,我不理解这个问题的根本原因
我的代码中是否有错误,或者这是否是一个bug
烧瓶蓝图
class get_dimension_json(Resource):
def get(self, dimension, hierarchy):
try:
test_recursive = TestRecursive(dimension, random.randint(1, 5) / 10)
result = test_recursive.recursive_function(random.randint(5, 15))
log.debug('result %s %s : %s', dimension, hierarchy, result)
return {'msg': 'result}, 200
except Exception as e:
log.debug('get_dimension_json get %s %s finished with errors', dimension, hierarchy)
log.debug(e)
return {'msg': repr(e)}, 500
api.add_resource(
get_dimension_json,
'/api/report/dimension-json/<string:dimension>/<string:hierarchy>',
)
这就是python的工作方式/一个常见的陷阱。
numbers
的初始化值/对象仅在首次解释函数时(在导入/运行模块上)计算一次,该对象在后续调用中重复使用。这就是为什么默认参数应始终是不可变的(例如,tuple)。有关详细信息,请阅读“可变默认参数"在python中。谢谢,知道这一点可以节省我很多时间……我阅读了相关内容并了解如何修复我的代码,但我并没有真正体会到在python中实现这一点的好处。在我看来,这只会导致代码更难测试,因为您必须使用默认参数multi测试每个函数les时间确保调用之间没有不必要的副作用…或者如果默认参数是可变的,则根本不使用默认参数…有一个SO线程专门说明了为什么会这样(tl;dr;:因为在python中,函数是一个对象,它只存储默认值)。还有一些指示说明了这是如何有用的。
import time
import logging
log = logging.getLogger(__name__)
class TestRecursive:
def __init__(self, name, seconds_delay):
self.name = name
self.seconds_delay = seconds_delay
def recursive_function(self, iterations, numbers=[]):
time.sleep(self.seconds_delay)
log.debug('%s - %s', self.name, iterations)
numbers.append(len(numbers) + 1)
if iterations > 0:
self.recursive_function(iterations - 1, numbers)
return numbers