之前看python
教程的时候,看到一个内容是:python
中任何对象都可以添加属性,包括函数。
当时想,给函数添加属性有什么意义吗?难道把函数当成数据对象去使用?
没想到,今天遇到了一个场景就需要用到这个。
场景如下:
就是求一个给定参数的阿克曼函数(Ackermann的结果是 2 的几次方的问题。比如
ackermann(2,4)
的结果将是2的几次方?
函数原型很简单:用python
表示也很简单:
def ackermann(i, j):
if i == 1 and j >= 1:
return 2 ** j
elif i >= 2 and j == 1:
return ackermann(i - 1, 2)
elif i >= 2 and j >= 2:
return ackermann(i - 1, ackermann(i, j - 1))
就这么一个简单的函数,但是这样返回的是函数的结果,而不是 2
的几次方。当然,拿到这个结果,然后去递归的/2
也是可以得到的,但是这个数字太大,以至于,再递归/2
的时候,会抛运行异常了。
我原先想着能不能使用闭包去实现。但是我对闭包也不熟悉,尝试了半天无果。我也猜测,这个场景,闭包无法实现。(欢迎指正)
于是,我投机取巧了一下,在原来的代码上面加了一行代码,完成了这个需求。
def ackermann(i, j):
if i == 1 and j >= 1:
ackermann.value = j # 没错,就是加了这一行
return 2 ** j
elif i >= 2 and j == 1:
return ackermann(i - 1, 2)
elif i >= 2 and j >= 2:
return ackermann(i - 1, ackermann(i, j - 1))
然后调用的时候,就这样子:
ackermann(2, 4)
print("ackermann(2, 4) -> 结果为2 的 {} 次方".format(ackermann.value))
# 输出如下:ackermann(2, 4) -> 结果为2 的 65536 次方
好了,这就是我遇到的python
函数属性的一个实际场景了。而且,目前为止,我没有找到除了函数属性之外的方式去实现这个需求(全局变量不算~)。
ps:这种实现方式并不好,因为调用者需要写两句代码,我希望的是,直接返回结果,待优化…