Python 为什么要使用函数嵌套函数 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
SlipStupig

Python 为什么要使用函数嵌套函数

  •  
  •   SlipStupig Feb 20, 2017 8336 views
    This topic created in 3355 days ago, the information mentioned may be changed or developed.

    看一些代码会写成函数中嵌套函数,例如:

     def func(): def new_func(): return 1 a = new_func()  

    这种写法和 lambda 和单独创建一个 function 有什么区别或优势吗?

    21 replies    2018-01-22 22:02:19 +08:00
    clino
        2
    clino  
       Feb 20, 2017
    对啊,要写闭包的时候很好用的
    RadishWind
        3
    RadishWind  
       Feb 20, 2017   1
    查看一下柯里化的定义,这样写返回的新函数能够保持当时的状态,而且能够达到惰性求值的效果(用到这个函数的时候再处理传入的参数)
    ansheng
        4
    ansheng  
       Feb 20, 2017
    例如装饰器传参,就是多层嵌套的函数,
    picasso250
        5
    picasso250  
       Feb 20, 2017
    因为 lambda 的限制
    firstway
        6
    firstway  
       Feb 20, 2017   1
    你的例子确实 lambda 也可以做到。但是下面的呢?

    def func(x):
    def new_func(y):
    return x+y
    return new_func

    >>> a = func(10)
    >>> a(3)
    13
    >>> a(5)
    15
    ic3z
        7
    ic3z  
       Feb 20, 2017 via Android
    也许是为了方便吧。脚本嘛
    Yinz
        8
    Yinz  
       Feb 20, 2017
    额,其实我也不是很了解这两种用法的差异的,不过一不小心就写了出来 @firstway

    In [1]: def func(x):
    ...: return lambda y:y+x
    ...:

    In [2]: a = func(10)

    In [3]: a(3)
    Out[3]: 13

    In [4]: a(5)
    Out[4]: 15
    will0404
        9
    will0404  
       Feb 20, 2017
    @firstway 你的例子不合适啊。

    >>> a = lambda x: lambda y: x + y
    >>> b = a(10)
    >>> b(3)
    13
    >>> b(5)
    15
    will0404
        10
    will0404  
       Feb 20, 2017
    因为 lambda 是匿名的,我想区别应该是名字是否有意义,比如递归吧。

    >>> def func(x, sum):
    ... if(x==0):
    ... return sum
    ... return func(x-1, sum + x)
    ...
    >>> func(10, 0)
    55

    lambda 大概写不出上面这个递归?
    fwrq41251
        11
    fwrq41251  
       Feb 20, 2017 via Android
    能省几个参数,函数的作用域小了
    gamexg
        12
    gamexg  
       Feb 21, 2017 via Android
    一般是返回一个函数指针时用。一般外部固定了函数指针的参数,但是自己又需要传递给函数指针一些数据,这样嵌套函数可以使得内部函数可以访问外部函数的变量。关键字:闭包,需求的例子:装饰器。

    不用 lambda 的原因是 lambda 限制太大,不方便。
    est
        13
    est  
       Feb 21, 2017
    这就是 meta 编程啊
    enenaaa
        14
    enenaaa  
       Feb 21, 2017
    lambda 你能多写几行么
    lll9p
        15
    lll9p  
       Feb 21, 2017 via Android
    Python 里 lambda 只能写一行啊
    drlalll
        16
    drlalll  
       Feb 21, 2017
    @gamexg
    需要做到这个的话直接用指针不行吗?
    gamexg
        17
    gamexg  
       Feb 21, 2017   1
    @drlalll 无法实现,像下面的装饰器例子:

    https://gist.github.com/GameXG/ed84b114067fb4a7b398cb811a9241ca

    需要将 @w(123) 的 123 传递给 fffff 函数,但是 fffff 函数是会被当作 hello3 参数给用户调用的,用户不会帮你把 123 传递进去,只能通过闭包的方式传递进去 123 .
    wizardoz
        18
    wizardoz  
       Feb 21, 2017
    lambda 写复杂的函数很麻烦啊
    sadscv
        19
    sadscv  
       Feb 21, 2017   2
    这是一种嵌套函数的写法,有时候它和 lambda 没什么区别,但有些情况下它会实现一个闭包,所以我姑且认为楼主是想知道闭包的特性.
    那么这里首先强烈建议楼主了解一下 namespace 与变量作用域的相关知识.
    http://python.jobbole.com/81367/
    如果只要了解闭包的概念,请参考这篇文章.
    http://blog.csdn.net/marty_fu/article/details/7679297
    如果想知道闭包的实现原理.那么你必须得明白函数调用过程.因为闭包本身就是调用一个函数反回另一个函数.
    这里推荐 UCSB 的教程,提供了一个交互式的函数调用演示程序.共6个课程,每个课程都很短,但看完这些你大概能对函数调用帧栈有初步了解.
    https://www.cs.ucsb.edu/~pconrad/cs8/topics.beta/theStack/01/
    到现在你已经可以开始探究 python 在函数调用中如何精妙地完成参数传递.
    http://www.jianshu.com/p/d00108741a18
    如果能坚持到这里,那么你已经停不下来了...函数调用过程中所有涉及到的源码作者都给出了分析,看完之后应该什么都明白了
    http://python.jobbole.com/83545/
    以下链接可以看看,也许能帮助你理解源码.
    http://www.cnblogs.com/hackerl/p/5985102.html
    http://eli.thegreenplace.net/2012/03/23/python-internals-how-callables-work/
    julyclyde
        20
    julyclyde  
       Feb 26, 2017
    一种劣习,让函数变成有状态的,或者叫不完全依赖于字面输入,还依赖一个隐藏输入的东西
    uygnef
        21
    uygnef  
       Jan 22, 2018
    我用这个是因为 有时候要用递归,把 helper 放函数里面可以把外面函数的变量当全局变量。
    另外就是 helper 只用这里会用,写外面不清晰。
    About     Help     Advertise     Blog     API     FAQ     Solana     2935 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 95ms UTC 15:06 PVG 23:06 LAX 08:06 JFK 11:06
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86