前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python + inspect 一行实现递归 fib 函数

Python + inspect 一行实现递归 fib 函数

作者头像
kifuan
发布2022-10-24 17:07:15
2810
发布2022-10-24 17:07:15
举报
文章被收录于专栏:随便写写-kifuan随便写写-kifuan

背景

有个裙友要看看用 lambda 能不能在一行里定义出来 fib 函数,并且不要那个根号五的数学公式,于是就有了这篇文章。

介绍

inspect 库可以帮助我们拿到 Python 上下文的各种信息,自然也包括了当前正在运行的函数。配合 eval 可以达到我们的目的。

实现

原始方法

虽然大家都知道,但还是放上来做一个对比。

代码语言:javascript
复制
def fib(n):
    if n in (1, 2):
        return 1
    return fib(n-1) + fib(n-2)

# 8
print(fib(6))

通过 inspect 获取当前函数

我目前只知道 codeobject 配合 eval 来执行的方法,如下:

代码语言:javascript
复制
import inspect
def fib():
    if n in (1, 2):
        return 1
    return eval(inspect.currentframe().f_code, {'n': n-1, 'inspect': inspect}) + \
        eval(inspect.currentframe().f_code, {'n': n-2, 'inspect': inspect})

# 8
print(eval(fib.__code__, {'n': 6, 'inspect': inspect}))

注意,此时我们就通过给 eval 的第二个参数指定函数运行时的环境(即globals),这样我们就可以在函数内部直接通过变量名访问了。

用 lambda 写成一行

还用了 __import__ 来导包,是真正的一行捏:

代码语言:javascript
复制
result = (lambda number:
    eval(
        (lambda: 1 if n in (1, 2) else
            eval(f().f_code, {'n': n-1, 'f': f}) +
            eval(f().f_code, {'n': n-2, 'f': f})
        ).__code__, 
        {'n': number, 'f': __import__('inspect').currentframe}
    )
)(6)

# 8
print(result)

注意不要改我们 lambda number 后边的参数名,如果也改成 n 的话,eval 会报错,下面是报错信息:

代码语言:javascript
复制
Traceback (most recent call last):
  File "test.py", line 1, in <module>
    result = (
  File "test.py", line 3, in <lambda>
    eval((lambda: 1 if n in (1, 2)
TypeError: code object passed to eval() may not contain free variables

因为此时内层函数用的 n 就类似 Lua 的 upvalue,或者 nonlocal,总之就是闭包里面的那个概念,它无法访问到就报错了。

总结

不觉得这很酷吗?很符合我对 Python 的想象,科技并带着趣味。😎

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • 介绍
  • 实现
    • 原始方法
      • 通过 inspect 获取当前函数
        • 用 lambda 写成一行
        • 总结
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档