Python 中如何实现 Golang 的闭包?

2017-12-22 00:13:21 +08:00
 awker

根据 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 中要怎么实现?

2501 次点击
所在节点    Python
16 条回复
Arnie97
2017-12-22 00:22:38 +08:00
def seq():
....i = 0
....def func():
........i += 1
........return i
....return func
rabbbit
2017-12-22 00:27:18 +08:00
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
2017-12-22 00:29:43 +08:00
@Arnie97 UnboundLocalError: local variable 'i' referenced before assignment
@rabbbit 输出结果不对
输出结果
```
1
2
3
4
5
```
Arnie97
2017-12-22 00:32:14 +08:00
一楼笔误,少贴了一行 nonlocal。

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

to
nextInt = intSeq()
print nextInt()
awker
2017-12-22 00:37:41 +08:00
@Arnie97 Python 3 ....
awker
2017-12-22 00:43:44 +08:00
@rabbbit
newInts = intSeq()
print nextInt()
-->
newInts = intSeq()
print newInts()
这样就行了
xpresslink
2017-12-22 12:44:52 +08:00
因为 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
2017-12-22 13:01:15 +08:00
为什么大家这么爱好实现一个有状态的函数?
这需求不是应该用对象吗?
araraloren
2017-12-22 13:50:01 +08:00
@xpresslink The key point is not `how to implement a generator`.
araraloren
2017-12-22 13:51:55 +08:00
@julyclyde
But sometimes its not worth create a class.
Use Closures is easy and convenient.
xpresslink
2017-12-22 14:33:57 +08:00
@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
2017-12-22 17:09:52 +08:00
yield 吧... python generator
quinoa42
2017-12-22 21:00:50 +08:00
@julyclyde object 和 closure 分别是 OOP 和 FP 对同一需求的不同实现,只不过现在很多语言同时支持这两种罢了
first class function (或者,按 python 的说法,functions as first class objects )都是需要语言支持 closure 才能实现的
julyclyde
2017-12-24 10:43:42 +08:00
@quinoa42 可是它表现为一个 function,而 function “应该是”无状态的,它的所有输入都应该被明确列出

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/416699

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX