2 回答

TA贡献1829条经验 获得超7个赞
Python 旨在通过解包运算符 * 或使用 lambda 使这变得相当容易
让我们来看看吧。
callstack = [] # initialize a list to serve as our stack.
# See also collections.deque for a queue.
然后我们可以定义我们的函数:
def somefunc(a, b, c):
do stuff...
然后将参数作为列表添加到堆栈中。
args = [a, b, c]
callstack.append((somefunc, args)) # append a tuple with the function
# and its arguments list.
# calls the next item in the callstack
def call_next(callstack):
func, args = callstack.pop() # unpack our tuple
func(*args) # calls the func with the args unpacked
* 运算符将您的列表解包并按顺序提供它们作为参数。您还可以使用双星运算符 (**) 解压缩关键字参数。
def call_next(callstack):
func, args, kwargs = callstack.pop() # unpack our tuple
func(*args, **kwargs) # calls the func with both args and kwargs unpacked.
另一种方法是创建一个 lambda。
def add(a, b):
return a + b
callstack = []
callstack.append(lambda: add(1, 2))
callstack.pop()() # pops the lambda function, then calls the lambda function,
# which just calls the function as you specified it.
瞧!所有功劳都归功于另一个线程中的作者。这里有一个问题:如果您将对象作为参数传递,它将作为引用传递。请小心,因为您可以在堆栈中调用对象之前对其进行修改。
def add(a, b, c):
return a + b + c
badlist = [1,2,3]
callstack.append((somefunc, badlist))
badlist = [2, 4, 6]
callstack.append((somefunc, badlist))
while len(callstack) > 0:
print(call_next(callstack))
# Prints:
12
12
你可以在 *args 版本中解决这个问题:
# make a shallow copy and pass that to the stack instead.
callstack.append((somefunc, list(badlist)))
在 lambda 函数中,整个事物都在调用时进行评估,因此即使通常不是引用的事物也表现得像引用。上述技巧不起作用,因此在创建 lambda 之前根据需要进行任何复制。
添加回答
举报