V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
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
awker
V2EX  ›  Python

Python 中如何实现 Golang 的闭包?

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

    根据 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
    Arnie97
        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
    rabbbit
        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()
    awker
        3
    awker  
    OP
       2017-12-22 00:29:43 +08:00
    @Arnie97 UnboundLocalError: local variable 'i' referenced before assignment
    @rabbbit 输出结果不对
    输出结果
    ```
    1
    2
    3
    4
    5
    ```
    Arnie97
        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
    rabbbit
        5
    rabbbit  
       2017-12-22 00:33:12 +08:00   ❤️ 2
    rabbbit
        6
    rabbbit  
       2017-12-22 00:36:29 +08:00   ❤️ 1
    newInts = intSeq()
    print nextInt()

    to
    nextInt = intSeq()
    print nextInt()
    awker
        7
    awker  
    OP
       2017-12-22 00:37:41 +08:00
    @Arnie97 Python 3 ....
    awker
        8
    awker  
    OP
       2017-12-22 00:43:44 +08:00
    @rabbbit
    newInts = intSeq()
    print nextInt()
    -->
    newInts = intSeq()
    print newInts()
    这样就行了
    xpresslink
        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
    >>>
    julyclyde
        10
    julyclyde  
       2017-12-22 13:01:15 +08:00   ❤️ 2
    为什么大家这么爱好实现一个有状态的函数?
    这需求不是应该用对象吗?
    araraloren
        11
    araraloren  
       2017-12-22 13:50:01 +08:00   ❤️ 1
    @xpresslink The key point is not `how to implement a generator`.
    araraloren
        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.
    xpresslink
        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.
    bonfy
        14
    bonfy  
       2017-12-22 17:09:52 +08:00
    yield 吧... python generator
    quinoa42
        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 才能实现的
    julyclyde
        16
    julyclyde  
       2017-12-24 10:43:42 +08:00
    @quinoa42 可是它表现为一个 function,而 function “应该是”无状态的,它的所有输入都应该被明确列出
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   887 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 20:52 · PVG 04:52 · LAX 12:52 · JFK 15:52
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.