首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python 学习手册
Python Cookbook
Python 基础教程
Python Sites
PyPI - Python Package Index
http://www.simple-is-better.com/
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
拉勾
V2EX  ›  Python

Python 中如何实现 Golang 的闭包?

  •  
  •   awker · 2017-12-22 00:13:21 +08:00 · 1547 次点击
    这是一个创建于 455 天前的主题,其中的信息可能已经有所发展或是发生改变。

    根据 Go by Example 里的 Closures 实现,想用 Python 实现一下, 没有成功

    Golang

    package main
    
    import "fmt"
    
    func intSeq() func() int {
    	i := 0
    	return func() int {
    		i += 1
    		return i
    	}
    }
    
    func main()  {
    	nextInt := intSeq()
    
    	fmt.Println(nextInt())
    	fmt.Println(nextInt())
    	fmt.Println(nextInt())
    	fmt.Println(nextInt())
    
    	// 一脸懵 为什么不重新初始化 intSeq(),值会一直添加???
    	newInts := intSeq()
    	fmt.Println(newInts())
    }
    

    输出

    1
    2
    3
    4
    1
    

    Python 2.7

    # coding: utf-8
    
    
    def intSeq():
        def func():
            i = 0
            i += 1
            return i
        return func
    
    if __name__ == "__main__":
        nextInt = intSeq()
        print nextInt()
        print nextInt()
        print nextInt()
        print nextInt()
    
        newInts = intSeq()
        print nextInt()
    
    

    输出结果:

    1
    1
    1
    1
    1
    

    话说 Python 中要怎么实现?

    16 回复  |  直到 2017-12-24 10:43:42 +08:00
        1
    Arnie97   2017-12-22 00:22:38 +08:00 via Android   ♥ 1
    def seq():
    ....i = 0
    ....def func():
    ........i += 1
    ........return i
    ....return func
        2
    rabbbit   2017-12-22 00:27:18 +08:00   ♥ 1
    def intSeq():
    i = [0]
    def func():
    i[0] += 1
    return i[0]
    return func

    if __name__ == "__main__":
    nextInt = intSeq()
    print nextInt()
    print nextInt()
    print nextInt()
    print nextInt()

    newInts = intSeq()
    print nextInt()
        3
    awker   2017-12-22 00:29:43 +08:00
    @Arnie97 UnboundLocalError: local variable 'i' referenced before assignment
    @rabbbit 输出结果不对
    输出结果
    ```
    1
    2
    3
    4
    5
    ```
        4
    Arnie97   2017-12-22 00:32:14 +08:00 via Android   ♥ 1
    一楼笔误,少贴了一行 nonlocal。

    def seq():
    ....i = 0
    ....def func():
    ........nonlocal i
    ........i += 1
    ........return i
    ....return func
        5
    rabbbit   2017-12-22 00:33:12 +08:00   ♥ 2
        6
    rabbbit   2017-12-22 00:36:29 +08:00   ♥ 1
    newInts = intSeq()
    print nextInt()

    to
    nextInt = intSeq()
    print nextInt()
        7
    awker   2017-12-22 00:37:41 +08:00
    @Arnie97 Python 3 ....
        8
    awker   2017-12-22 00:43:44 +08:00
    @rabbbit
    newInts = intSeq()
    print nextInt()
    -->
    newInts = intSeq()
    print newInts()
    这样就行了
        9
    xpresslink   2017-12-22 12:44:52 +08:00   ♥ 1
    因为 Python 不需这么玩唉
    Python 的哲学是不要自己造轮子。

    >>> def g_factory():
    i = 1
    while True:
    yield i
    i += 1


    >>> g = g_factory()
    >>> next(g)
    1
    >>> next(g)
    2
    >>>

    >>> from itertools import count
    >>> c = count(1)
    >>> next(c)
    1
    >>> next(c)
    2
    >>>

    >>> from itertools import cycle
    >>> c = cycle([1,2,3])
    >>> next(c)
    1
    >>> next(c)
    2
    >>> next(c)
    3
    >>> next(c)
    1
    >>>
        10
    julyclyde   2017-12-22 13:01:15 +08:00   ♥ 2
    为什么大家这么爱好实现一个有状态的函数?
    这需求不是应该用对象吗?
        11
    araraloren   2017-12-22 13:50:01 +08:00   ♥ 1
    @xpresslink The key point is not `how to implement a generator`.
        12
    araraloren   2017-12-22 13:51:55 +08:00   ♥ 1
    @julyclyde
    But sometimes its not worth create a class.
    Use Closures is easy and convenient.
        13
    xpresslink   2017-12-22 14:33:57 +08:00   ♥ 1
    @araraloren To implement a generator is must-know trick for pythoneer, the key point is 'how to solve the problem or fulfill the requirement. you are using Python, you should obey its philosophy. generator is better solution, if you just want better enclosure go lisp.
        14
    bonfy   2017-12-22 17:09:52 +08:00
    yield 吧... python generator
        15
    quinoa42   2017-12-22 21:00:50 +08:00   ♥ 1
    @julyclyde object 和 closure 分别是 OOP 和 FP 对同一需求的不同实现,只不过现在很多语言同时支持这两种罢了
    first class function (或者,按 python 的说法,functions as first class objects )都是需要语言支持 closure 才能实现的
        16
    julyclyde   2017-12-24 10:43:42 +08:00
    @quinoa42 可是它表现为一个 function,而 function “应该是”无状态的,它的所有输入都应该被明确列出
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   1072 人在线   最高记录 4385   ·  
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 18ms · UTC 18:06 · PVG 02:06 · LAX 11:06 · JFK 14:06
    ♥ Do have faith in what you're doing.
    沪ICP备16043287号-1