好程序员分享循环内的回调函数

简介:   好程序员分享循环内的回调函数,问题出现在循环体内的回调函数,用一个很简单的例子举例:  for x in xrange(3):1.  print "requests begin:%s"%x2.

  好程序员分享循环内的回调函数,问题出现在循环体内的回调函数,用一个很简单的例子举例:

  for x in xrange(3):
1.

  print "requests begin:%s"%x


2.

  def callback(respon):


3.

  print x


4.

  print respon.body


5.

  client.fetch("http://httpbin.org/get?x=%s" % x, callback)

  此例子忽略了等待回调函数完成的wait实现(不实现这个会导致作为单个文件运行的时候,还没获得结果就退出了),在tornado.testing中的AsyncTestCase提供了相关功能
  httpbin.org/get这个地址的作用是返回了请求的json对象,形如:
  {
1.

  "args": {


2.

  "x": "0"


3.

  },


4.

  "headers": {


5.

  "Accept-Encoding": "gzip",


6.

  "Connection": "close",


7.

  "Host": "httpbin.org",


8.

  "X-Request-Id": "95df3c15-7ed0-4a6d-830d-fb9629e66515"


9.

  },


10.

  "origin": "192.81.129.91",


11.

  "url": "http://httpbin.org/get?x=0"


12.

  }

  但实际上,由于回调函数特殊的特性:访问闭包内局部变量的当前值。易知,在第一个请求
  http://httpbin.org/get?x=0的url返回时,循环早已结束,此时的x已经为2,因此实际上虽然httpbin.org返回的json告诉我们,get参数里的x为0,但闭包内访问到的x已经是2了
  解决方法我想了两个,一个是利用回调函数构造时的变量空间,在构造函数时即产生这个参数,形如:
  client = AsyncHTTPClient(self.io_loop)
1.

  for x in xrange(3):


2.

  def callback(respon,num=x):


3.

  print x, num


4.

  print respon.body


5.

  if num == 2:


6.

  self.stop()


7.

  client.fetch("http://httpbin.org/get?x=%s" % x, wrap(x))

  一种是再包一层闭包(这层闭包也可以放在for外面):
  client = AsyncHTTPClient(self.io_loop)
1.

  for x in xrange(3):


2.

  def wrap(number):


3.

  num = number


4.

  def callback(respon):


5.

  print x, num


6.

  print respon.body


7.

  if num == 2:


8.

  self.stop()


9.

  return callback


10.

  client.fetch("http://httpbin.org/get?x=%s" % x, wrap(x))


11.

  #wrap放在for外面:


12.

  client = AsyncHTTPClient(self.io_loop)


13.

  def wrap(number):


14.

  num = number


15.

  def callback(respon):


16.

  print x, num


17.

  print respon.body


18.

  if num == 2:


19.

  self.stop()


20.

  return callback


21.

  for x in xrange(3):


22.

  client.fetch("http://httpbin.org/get?x=%s" % x, wrap(x))

  思索了一下,闭包的内存占用问题应当是不可避免的?当循环体的每一项(x)是一个大内存对象时,内存占用等同于不用迭代器用列表进行循环,除了这两种不知道还有没有更优雅的解决方案。。

相关文章
|
5天前
|
Java
回调函数在异步编程中的作用与实现方式
回调函数在异步编程中的作用与实现方式
|
14天前
|
设计模式 算法 Python
Python回调函数中的循环艺术:深入探索for循环的回调应用
Python回调函数中的循环艺术:深入探索for循环的回调应用
9 1
|
22天前
|
存储 算法 Swift
Swift开发——循环执行方式
Swift语言中的循环主要包括`for-in`和`while`结构。`for-in`适用于遍历数字区间、字符串和字典,支持使用`stride`函数定制步进。字典遍历时,可以用二元元组`(k, v)`访问键值对。`while`循环有标准形式和`repeat-while`形式,确保至少执行一次循环体。程序示例展示了`for-in`和不同`while`结构的用法,包括计算阶乘、奇数和、加密字符串以及最大公约数和最小公倍数。
16 0
Swift开发——循环执行方式
|
2月前
javascirpt中的for...in循环
javascirpt中的for...in循环
|
2月前
|
搜索推荐 C语言
C语言简单实现冒泡函数
C语言简单实现冒泡函数
C4.
|
2月前
|
程序员 C语言 开发者
C语言中如何改变循环执行的状态
C语言中如何改变循环执行的状态
C4.
26 0
|
9月前
|
存储 编译器 C语言
回调函数的应用(sqort函数)——指针进阶(三)
回调函数的应用(sqort函数)——指针进阶(三)
20 0
JavaScirpt基础do while循环
JavaScirpt基础do while循环
67 0
简单手写async函数,让生成器函数自动执行
简单手写async函数,让生成器函数自动执行
177 0
Go语言条件,循环,函数
select 语句 select 随机执行一个可运行的 case。如果没有 case 可运行,它将阻塞,直到有 case 可运行。一个默认的子句应该总是可运行的。
86 0