Python Flask-递归函数调用时忽略的默认参数(单独调用之间累积的值)

Python Flask-递归函数调用时忽略的默认参数(单独调用之间累积的值),python,Python,我在并行调用FlaskAPI时遇到了一个问题(只有2个实例出现了这个问题)。在我的完整代码中,我从表中请求数据,然后创建一个json树,该树将显示在前端。我注意到我的树看起来很奇怪,第一棵树还行,但是第二棵树包含了第一棵树的所有节点,然后只包含了第二棵树的节点) 我调用一个递归函数来构建我的树,它看起来像是两个并行执行之间“共享”了一些变量(这对我来说没有意义,因为我调用了一个对象的两个不同实例的方法) 我创建了下面的示例,它复制了我的问题 结果变量应该是一个列表,其中包含每个递归执行的数字(因

我在并行调用FlaskAPI时遇到了一个问题(只有2个实例出现了这个问题)。在我的完整代码中,我从表中请求数据,然后创建一个json树,该树将显示在前端。我注意到我的树看起来很奇怪,第一棵树还行,但是第二棵树包含了第一棵树的所有节点,然后只包含了第二棵树的节点)

我调用一个递归函数来构建我的树,它看起来像是两个并行执行之间“共享”了一些变量(这对我来说没有意义,因为我调用了一个对象的两个不同实例的方法)

我创建了下面的示例,它复制了我的问题

结果变量应该是一个列表,其中包含每个递归执行的数字(因此对于5,我希望是[1 2 3 4 5]

但是,当我多次执行代码(通过执行刷新)时,我可以看到我的结果列表变得更大了(因此在两次刷新之后,我的列表是[1 2 3…75](递归只能执行5到15次)

我没有在递归方法的初始调用中指定numbers参数:

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