2004年08月01日 星期日 13:05
Hollo hoxide:
迭代器和简单生成器
还是 Limodou 讲的比较亲切!到他的Blog 上去查
[Python学习]Iterator 和 Generator的学习心得
"""
Iterator是迭代器的意思,它的作用是一次产生一个数据项,直到没有为止。这样在 for 循环中就可以对它进行循环处理了。那么它与一般的序列类型(list, tuple等)有什么区别呢?它一次只返回一个数据项,占用更少的内存。但它需要记住当前的状态,以便返回下一数据项。它是一个有着next()方法的对象。而序列类型则保存了所有的数据项,它们的访问是通过索引进行的。
使用Iterator的好处除了节省内存外,还有一个好处就是可以把非线性化的处理转换成线性化的方式来进行处理。如对一棵树的访问,传统的方法可以使用递归函数来处理,下面是对树的一个中序遍历的示例:
例1:
def deal_tree(node):
if not node:
return
if node.leftnode:
deal_tree(node.leftnode)
process(node)
if node.rightnode:
deal_tree(node.rightnode)
deal_tree(root)
可以看出,对结点的处理函数与递归函数是混在一起的,不是很清晰。使用Iterator的方式改写后为:
例2:
1 def walk_tree(node):
2 if not node:
3 return
4 if node.leftnode:
5 for i in walk_tree(node.leftnode):
6 yield i
7 yield node
8 if node.rightnode:
9 for i in walk_tree(node.rightnode):
10 yield i
11
12 for node in wald_tree(root):
13 process(node)
生成结点的过程仍然是一个递归过程,但对于返回后的结点的处理就变成了线性化的处理,结构上要清晰多了。第5-6,9-10行要特别注意,如果不这样处理直接调用walk_tree的话,其实返回的是一个Iterator对象,而不是想要的元素。
象上面的walk_tree函数在 Python 中可以叫作Generator--产生器,它的作用是生成一个Iterator的对象。那么它主要是将一个函数过程进行封装,转化为Iterator对象,每执行到yield语句时,函数的状态,数据都保存起来,然后返回相应的值。取下一个值的时候,再从上次运行的地方继续运行,如果遇上yield语句,则再次保存状态,返回结果,如果不存在值了,则自动引发一个异常StopIteration,从而Iterator不再产生新的值。从此处我们可以了解,这里的Iterator只可以遍历一次,但并非所有的都是这样,你完全可以对其进行控制。
下面我再介绍一下如何构造自已的Iterator。很简单,创建一个类,满足Iterator的协议,也就是要定义__iter__方法,它返回一个Iterator对象,这个对象必须有next方法,因此我们可以总结出两种对象模式:
class A:
def __iter__(self):
return self
def next(self):
if has_next_value(self):
return next_value
else:
raise StopIterator
class B:
def __iter__(self):
return iterator_obj
A,B分别为两种对象模式(都是示例代码)。模式A表示,在A中定义了next方法,因此__iter__简单地返回自身即可。当不存在下一个值时,引发StopIterator异常。模式B表示,它使用了其它的Iterator对象,因此只需要定义__iter__即可,next不需要定义,因为返回的Iterator对象已经含有next方法了。如果是自已实现next方法,那么在返回值之前需要记住当前的状态,以便下一次运行时,可以取下一个值。
第2个例子好象与这里讲的不一样啊。这就是前面讲的Generator,它的作用就是把一个函数转换成一个Iterator,它自动保存状态,中间数据,引发异常,全部是自动化了。而且它只可以遍历一次。如果想再次遍历,只有重新生成新的Iterator对象才可以。
在最新的 Python 2.4 版中新增了Genetaor Expression方式,它是用来生成简单的,在函数调用需要序列参数时的一种Iterator写法,语法就象是list comprehension的格式,如:
>>> sum(i*i for i in range(10)) # sum of squares
285
不过这种写法必须要在小括号对中,因此它的使用是有限的。它的目的主要是想更好的使用内存。
前面我们提到不是所有的Iterator只可以遍历一次(使用Generator生成的只能遍历一次),你完全可以控制它重新遍历。比如我们可以在Iterator对象中增加一个复位方法,用来将内部的计数恢复到开始状态,这样我们就可以重新遍历了。
下面我们总结一下:
Iterator对象:具有__iter__方法,和next方法。当没有新值时引发StopIteration异常。
Iterator的好处:在某些情况下可以使程序结构清晰,如将递归等非线性处理转为线性处理。可以减少内存的占用。
Generator:将一个函数转化成Iterator对象的方法。使用它只需要在函数中需要返回值的时候调用yield语句。它是生成Iterator对象的简单方法,只适用于函数。
以上是我学习Iterator和Genetator的一点心得,如有不对的地方,欢迎交流。
"""
不过使用生成器,提升的性能有限吧!
主要还是程序更加易读是也乎?
/******** [2004-08-01]13:01:42 ; hoxide wrote:
hoxide> HD,您好!
hoxide> 大家最好先了解一下生成器的有关知识:IBM上的《可爱的
hoxide> Python:迭代器和简单生成器》:
hoxide> http://www-900.ibm.com/developerWorks/cn/linux/sdk/python/charm-20/index.shtml
hoxide> 昨天给的代码还有点错误,修改的代码(其实只改了打星号的地方):
hoxide> def testserver(self):
hoxide> """向服务器发的测试报文"""
hoxide> try:
hoxide> self.pp.next()
hoxide> self.call = reactor.callLater(0,self.testserver)
hoxide> return
hoxide> except StopIteration:
hoxide> pass
hoxide> def __init__(self):
hoxide> self.pp=self.sendQQ()
hoxide> ussp.USSClientQueueProtocol.__init__(self)
hoxide> def sendQQ(self):
hoxide> global nownum
hoxide> global count
hoxide> i=1
hoxide> while i < count:
hoxide> message = usspmsg.USSPMessage()
hoxide> message.setMsgName('mail_counter')
hoxide> message.body.setField('uid',str(i))
hoxide> while self.factory.sendQueue.full(): #*
hoxide> yield None #**
hoxide> self.factory.sendQueue.put_nowait(message)
hoxide> i += 1
hoxide> nownum=i
hoxide> self.disconnect()
hoxide> 这里真正的处理是在sendQQ这个函数定义的.self.pp是生成器的实例,由__init__()生成,testserver只是调度完成这个处理的函数,而且是和具体的处理独立的,他只是简单得实现了当处理"暂停"后的重新启动.
hoxide> 真正神奇的地方是打星号的行.他测试sendQueue确定是否能发出message,如果不能就会执行yield
hoxide> None,这时函数就终止在**这行,直到在有.next()方法调用时再从这句开始执行.
hoxide> 这个好处是原来的处理流程可以很顺利得进行.不需要保存中间变量.注意0731a的testserver能正确得发出所有message,是因为恰巧有全局变量nownum完全确定处理的执行状态了.但事事上一般的处理不会那么简单,有复杂的状态组合(上面的代码并没用nownum,而是用了循环变量i,注意他不是全局的!!!!!).正像zoomq昨天说的0731a的testserver在queue满的时候前面对message的处理就被抛弃了,但在这个生成器版本,先前对message的处理没有被抛弃.
hoxide> 个人觉得这个生成器版本还是不够完美,异步传输还是应该以线程为基础进行.下一个版本可能是基于生成器的简单线程:)
hoxide> 说得不是很明白,我不清楚大家对什么地方有疑问.
hoxide> ===== 2004-08-01 00:33:08 您在来信中写道:=======
>>细说说,为什么说是生成器版的呢?
>>
>>On Sat, 31 Jul 2004 23:22:53 +0800, hoxide
>><hoxide_dirac at yahoo.com.cn> wrote:
>>> python-chinese,您好!
>>>
>>>
>>> 为什么要用生成器,现在的testserver的执行流程只依赖于nownum,而事实上通常的服务要依赖于整个运行流程.另外这样的写法可将窗口部分的代码抽出.
>>>
>>> 致
>>> 礼!
>>>
>>> hoxide
>>> hoxide_dirac at yahoo.com.cn
>>> 2004-07-31
>>>
>>>
>>>
>>
>>
>>--
>>HD(燃烧中的火)
>>我工作我快乐,我勤奋我收获。请与我一起快乐,与我一起收获。
>>_______________________________________________
>>python-chinese list
>>python-chinese at lists.python.cn
>>http://python.cn/mailman/listinfo/python-chinese
>>
hoxide> = = = = = = = = = = = = = = = = = = = =
hoxide> 致
hoxide> 礼!
hoxide> hoxide
hoxide> hoxide_dirac at yahoo.com.cn
hoxide> 2004-08-01
********************************************/
--
Free as in Freedom
Zoom.Quiet
#=========================================#
]Time is unimportant, only life important![
#=========================================#
sender is the Bat!2.12.00
2004年08月01日 星期日 13:28
Zoom.Quiet,您好! 是的,这个设置不是为了提供性能. ======= 2004-08-01 13:05:29 您在来信中写道:======= >Hollo hoxide: > > 迭代器和简单生成器 >还是 Limodou 讲的比较亲切!到他的Blog 上去查 >[Python学习]Iterator 和 Generator的学习心得 >""" >Iterator是迭代器的意思,它的作用是一次产生一个数据项,直到没有为止。这样在 for 循环中就可以对它进行循环处理了。那么它与一般的序列类型(list, tuple等)有什么区别呢?它一次只返回一个数据项,占用更少的内存。但它需要记住当前的状态,以便返回下一数据项。它是一个有着next()方法的对象。而序列类型则保存了所有的数据项,它们的访问是通过索引进行的。 > >使用Iterator的好处除了节省内存外,还有一个好处就是可以把非线性化的处理转换成线性化的方式来进行处理。如对一棵树的访问,传统的方法可以使用递归函数来处理,下面是对树的一个中序遍历的示例: > >例1: > >def deal_tree(node): > if not node: > return > if node.leftnode: > deal_tree(node.leftnode) > process(node) > if node.rightnode: > deal_tree(node.rightnode) > >deal_tree(root) > >可以看出,对结点的处理函数与递归函数是混在一起的,不是很清晰。使用Iterator的方式改写后为: > >例2: > >1 def walk_tree(node): >2 if not node: >3 return >4 if node.leftnode: >5 for i in walk_tree(node.leftnode): >6 yield i >7 yield node >8 if node.rightnode: >9 for i in walk_tree(node.rightnode): >10 yield i >11 >12 for node in wald_tree(root): >13 process(node) > >生成结点的过程仍然是一个递归过程,但对于返回后的结点的处理就变成了线性化的处理,结构上要清晰多了。第5-6,9-10行要特别注意,如果不这样处理直接调用walk_tree的话,其实返回的是一个Iterator对象,而不是想要的元素。 > >象上面的walk_tree函数在 Python 中可以叫作Generator--产生器,它的作用是生成一个Iterator的对象。那么它主要是将一个函数过程进行封装,转化为Iterator对象,每执行到yield语句时,函数的状态,数据都保存起来,然后返回相应的值。取下一个值的时候,再从上次运行的地方继续运行,如果遇上yield语句,则再次保存状态,返回结果,如果不存在值了,则自动引发一个异常StopIteration,从而Iterator不再产生新的值。从此处我们可以了解,这里的Iterator只可以遍历一次,但并非所有的都是这样,你完全可以对其进行控制。 > >下面我再介绍一下如何构造自已的Iterator。很简单,创建一个类,满足Iterator的协议,也就是要定义__iter__方法,它返回一个Iterator对象,这个对象必须有next方法,因此我们可以总结出两种对象模式: > >class A: > def __iter__(self): > return self > > def next(self): > if has_next_value(self): > return next_value > else: > raise StopIterator > >class B: > def __iter__(self): > return iterator_obj > >A,B分别为两种对象模式(都是示例代码)。模式A表示,在A中定义了next方法,因此__iter__简单地返回自身即可。当不存在下一个值时,引发StopIterator异常。模式B表示,它使用了其它的Iterator对象,因此只需要定义__iter__即可,next不需要定义,因为返回的Iterator对象已经含有next方法了。如果是自已实现next方法,那么在返回值之前需要记住当前的状态,以便下一次运行时,可以取下一个值。 > >第2个例子好象与这里讲的不一样啊。这就是前面讲的Generator,它的作用就是把一个函数转换成一个Iterator,它自动保存状态,中间数据,引发异常,全部是自动化了。而且它只可以遍历一次。如果想再次遍历,只有重新生成新的Iterator对象才可以。 > >在最新的 Python 2.4 版中新增了Genetaor Expression方式,它是用来生成简单的,在函数调用需要序列参数时的一种Iterator写法,语法就象是list comprehension的格式,如: > >>>> sum(i*i for i in range(10)) # sum of squares >285 > >不过这种写法必须要在小括号对中,因此它的使用是有限的。它的目的主要是想更好的使用内存。 > >前面我们提到不是所有的Iterator只可以遍历一次(使用Generator生成的只能遍历一次),你完全可以控制它重新遍历。比如我们可以在Iterator对象中增加一个复位方法,用来将内部的计数恢复到开始状态,这样我们就可以重新遍历了。 > >下面我们总结一下: > >Iterator对象:具有__iter__方法,和next方法。当没有新值时引发StopIteration异常。 > >Iterator的好处:在某些情况下可以使程序结构清晰,如将递归等非线性处理转为线性处理。可以减少内存的占用。 > >Generator:将一个函数转化成Iterator对象的方法。使用它只需要在函数中需要返回值的时候调用yield语句。它是生成Iterator对象的简单方法,只适用于函数。 > >以上是我学习Iterator和Genetator的一点心得,如有不对的地方,欢迎交流。 >""" >不过使用生成器,提升的性能有限吧! >主要还是程序更加易读是也乎? > >/******** [2004-08-01]13:01:42 ; hoxide wrote: > >hoxide> HD,您好! > >hoxide> 大家最好先了解一下生成器的有关知识:IBM上的《可爱的 >hoxide> Python:迭代器和简单生成器》: >hoxide> http://www-900.ibm.com/developerWorks/cn/linux/sdk/python/charm-20/index.shtml > >hoxide> 昨天给的代码还有点错误,修改的代码(其实只改了打星号的地方): > >hoxide> def testserver(self): >hoxide> """向服务器发的测试报文""" >hoxide> try: >hoxide> self.pp.next() >hoxide> self.call = reactor.callLater(0,self.testserver) >hoxide> return >hoxide> except StopIteration: >hoxide> pass > >hoxide> def __init__(self): >hoxide> self.pp=self.sendQQ() >hoxide> ussp.USSClientQueueProtocol.__init__(self) > >hoxide> def sendQQ(self): >hoxide> global nownum >hoxide> global count >hoxide> i=1 >hoxide> while i < count: >hoxide> message = usspmsg.USSPMessage() >hoxide> message.setMsgName('mail_counter') >hoxide> message.body.setField('uid',str(i)) >hoxide> while self.factory.sendQueue.full(): #* >hoxide> yield None #** >hoxide> self.factory.sendQueue.put_nowait(message) >hoxide> i += 1 >hoxide> nownum=i >hoxide> self.disconnect() > >hoxide> 这里真正的处理是在sendQQ这个函数定义的.self.pp是生成器的实例,由__init__()生成,testserver只是调度完成这个处理的函数,而且是和具体的处理独立的,他只是简单得实现了当处理"暂停"后的重新启动. > >hoxide> 真正神奇的地方是打星号的行.他测试sendQueue确定是否能发出message,如果不能就会执行yield >hoxide> None,这时函数就终止在**这行,直到在有.next()方法调用时再从这句开始执行. >hoxide> 这个好处是原来的处理流程可以很顺利得进行.不需要保存中间变量.注意0731a的testserver能正确得发出所有message,是因为恰巧有全局变量nownum完全确定处理的执行状态了.但事事上一般的处理不会那么简单,有复杂的状态组合(上面的代码并没用nownum,而是用了循环变量i,注意他不是全局的!!!!!).正像zoomq昨天说的0731a的testserver在queue满的时候前面对message的处理就被抛弃了,但在这个生成器版本,先前对message的处理没有被抛弃. > >hoxide> 个人觉得这个生成器版本还是不够完美,异步传输还是应该以线程为基础进行.下一个版本可能是基于生成器的简单线程:) > >hoxide> 说得不是很明白,我不清楚大家对什么地方有疑问. > > >hoxide> ===== 2004-08-01 00:33:08 您在来信中写道:======= > >>>细说说,为什么说是生成器版的呢? >>> >>>On Sat, 31 Jul 2004 23:22:53 +0800, hoxide >>><hoxide_dirac at yahoo.com.cn> wrote: >>>> python-chinese,您好! >>>> >>>> >>>> 为什么要用生成器,现在的testserver的执行流程只依赖于nownum,而事实上通常的服务要依赖于整个运行流程.另外这样的写法可将窗口部分的代码抽出. >>>> >>>> 致 >>>> 礼! >>>> >>>> hoxide >>>> hoxide_dirac at yahoo.com.cn >>>> 2004-07-31 >>>> >>>> >>>> >>> >>> >>>-- >>>HD(燃烧中的火) >>>我工作我快乐,我勤奋我收获。请与我一起快乐,与我一起收获。 >>>_______________________________________________ >>>python-chinese list >>>python-chinese at lists.python.cn >>>http://python.cn/mailman/listinfo/python-chinese >>> > >hoxide> = = = = = = = = = = = = = = = = = = = = > > >hoxide> 致 >hoxide> 礼! > > >hoxide> hoxide >hoxide> hoxide_dirac at yahoo.com.cn >hoxide> 2004-08-01 > > > >********************************************/ > >-- >Free as in Freedom > > Zoom.Quiet > >#=========================================# >]Time is unimportant, only life important![ >#=========================================# > >sender is the Bat!2.12.00 > >_______________________________________________ >python-chinese list >python-chinese at lists.python.cn >http://python.cn/mailman/listinfo/python-chinese = = = = = = = = = = = = = = = = = = = = 致 礼! hoxide hoxide_dirac at yahoo.com.cn 2004-08-01
2004年08月01日 星期日 13:30
python-chinese,您好! 致 礼! hoxide hoxide_dirac at yahoo.com.cn 2004-08-01 -------------- next part -------------- A non-text attachment was scrubbed... Name: ussc.py Type: application/octet-stream Size: 5068 bytes Desc: not available Url : http://lists.exoweb.net/pipermail/python-chinese/attachments/20040801/e7b5c01b/ussc.obj
2004年08月01日 星期日 14:07
hoxide,您好!
其实不丢message也可以,这样不用使用生成器。只要把message生成放到else中就行了。因为那时是可以发送数据的。之所以丢是因为先生成了message,然后才判断是否可以发送,如果不能发送自然就丢了。如果改到可以发送才生成message就不会丢了。
while nownum < count:
if self.factory.sendQueue.full():
self.call = reactor.callLater(0, self.testserver)
return
else:
message = usspmsg.USSPMessage() #*
message.setMsgName('mail_counter') #*
message.body.setField('uid',str(nownum)) #* 这几行移下来了
self.factory.sendQueue.put_nowait(message)
nownum += 1
======= 2004-08-01 12:19:47 您在来信中写道:=======
>HD,您好!
>
>大家最好先了解一下生成器的有关知识:IBM上的《可爱的 Python:迭代器和简单生成器》: http://www-900.ibm.com/developerWorks/cn/linux/sdk/python/charm-20/index.shtml
>
>昨天给的代码还有点错误,修改的代码(其实只改了打星号的地方):
>
> def testserver(self):
> """向服务器发的测试报文"""
> try:
> self.pp.next()
> self.call = reactor.callLater(0,self.testserver)
> return
> except StopIteration:
> pass
>
> def __init__(self):
> self.pp=self.sendQQ()
> ussp.USSClientQueueProtocol.__init__(self)
>
> def sendQQ(self):
> global nownum
> global count
> i=1
> while i < count:
> message = usspmsg.USSPMessage()
> message.setMsgName('mail_counter')
> message.body.setField('uid',str(i))
> while self.factory.sendQueue.full(): #*
> yield None #**
> self.factory.sendQueue.put_nowait(message)
> i += 1
> nownum=i
> self.disconnect()
>
>这里真正的处理是在sendQQ这个函数定义的.self.pp是生成器的实例,由__init__()生成,testserver只是调度完成这个处理的函数,而且是和具体的处理独立的,他只是简单得实现了当处理"暂停"后的重新启动.
>
>真正神奇的地方是打星号的行.他测试sendQueue确定是否能发出message,如果不能就会执行yield None,这时函数就终止在**这行,直到在有.next()方法调用时再从这句开始执行.
>这个好处是原来的处理流程可以很顺利得进行.不需要保存中间变量.注意0731a的testserver能正确得发出所有message,是因为恰巧有全局变量nownum完全确定处理的执行状态了.但事事上一般的处理不会那么简单,有复杂的状态组合(上面的代码并没用nownum,而是用了循环变量i,注意他不是全局的!!!!!).正像zoomq昨天说的0731a的testserver在queue满的时候前面对message的处理就被抛弃了,但在这个生成器版本,先前对message的处理没有被抛弃.
>
>个人觉得这个生成器版本还是不够完美,异步传输还是应该以线程为基础进行.下一个版本可能是基于生成器的简单线程:)
>
>说得不是很明白,我不清楚大家对什么地方有疑问.
>
>
>===== 2004-08-01 00:33:08 您在来信中写道:=======
>
>>细说说,为什么说是生成器版的呢?
>>
>>On Sat, 31 Jul 2004 23:22:53 +0800, hoxide <hoxide_dirac at yahoo.com.cn> wrote:
>>> python-chinese,您好!
>>>
>>> 为什么要用生成器,现在的testserver的执行流程只依赖于nownum,而事实上通常的服务要依赖于整个运行流程.另外这样的写法可将窗口部分的代码抽出.
>>>
>>> 致
>>> 礼!
>>>
>>> hoxide
>>> hoxide_dirac at yahoo.com.cn
>>> 2004-07-31
>>>
>>>
>>>
>>
>>
>>--
>>HD(燃烧中的火)
>>我工作我快乐,我勤奋我收获。请与我一起快乐,与我一起收获。
>>_______________________________________________
>>python-chinese list
>>python-chinese at lists.python.cn
>>http://python.cn/mailman/listinfo/python-chinese
>>
>
>= = = = = = = = = = = = = = = = = = = =
>
>
> 致
>礼!
>
>
> hoxide
> hoxide_dirac at yahoo.com.cn
> 2004-08-01
>
>_______________________________________________
>python-chinese list
>python-chinese at lists.python.cn
>http://python.cn/mailman/listinfo/python-chinese
>
= = = = = = = = = = = = = = = = = = = =
致
礼!
limodou
chatme at 263.net
2004-08-01
2004年08月01日 星期日 14:31
limodou,您好!
这点我直到但是程序还是依赖一个全局变量,对于复杂的情况,这种用法是不好的,首先明显得会带来名字空间的污染,其次如果程序执行的上下文关系复杂,那么也就不是几个全局变量能轻松解决的.
======= 2004-08-01 14:07:21 您在来信中写道:=======
>hoxide,您好!
>
> 其实不丢message也可以,这样不用使用生成器。只要把message生成放到else中就行了。因为那时是可以发送数据的。之所以丢是因为先生成了message,然后才判断是否可以发送,如果不能发送自然就丢了。如果改到可以发送才生成message就不会丢了。
>
> while nownum < count:
> if self.factory.sendQueue.full():
> self.call = reactor.callLater(0, self.testserver)
> return
> else:
> message = usspmsg.USSPMessage() #*
> message.setMsgName('mail_counter') #*
> message.body.setField('uid',str(nownum)) #* 这几行移下来了
> self.factory.sendQueue.put_nowait(message)
> nownum += 1
>
>======= 2004-08-01 12:19:47 您在来信中写道:=======
>
>>HD,您好!
>>
>>大家最好先了解一下生成器的有关知识:IBM上的《可爱的 Python:迭代器和简单生成器》: http://www-900.ibm.com/developerWorks/cn/linux/sdk/python/charm-20/index.shtml
>>
>>昨天给的代码还有点错误,修改的代码(其实只改了打星号的地方):
>>
>> def testserver(self):
>> """向服务器发的测试报文"""
>> try:
>> self.pp.next()
>> self.call = reactor.callLater(0,self.testserver)
>> return
>> except StopIteration:
>> pass
>>
>> def __init__(self):
>> self.pp=self.sendQQ()
>> ussp.USSClientQueueProtocol.__init__(self)
>>
>> def sendQQ(self):
>> global nownum
>> global count
>> i=1
>> while i < count:
>> message = usspmsg.USSPMessage()
>> message.setMsgName('mail_counter')
>> message.body.setField('uid',str(i))
>> while self.factory.sendQueue.full(): #*
>> yield None #**
>> self.factory.sendQueue.put_nowait(message)
>> i += 1
>> nownum=i
>> self.disconnect()
>>
>>这里真正的处理是在sendQQ这个函数定义的.self.pp是生成器的实例,由__init__()生成,testserver只是调度完成这个处理的函数,而且是和具体的处理独立的,他只是简单得实现了当处理"暂停"后的重新启动.
>>
>>真正神奇的地方是打星号的行.他测试sendQueue确定是否能发出message,如果不能就会执行yield None,这时函数就终止在**这行,直到在有.next()方法调用时再从这句开始执行.
>>这个好处是原来的处理流程可以很顺利得进行.不需要保存中间变量.注意0731a的testserver能正确得发出所有message,是因为恰巧有全局变量nownum完全确定处理的执行状态了.但事事上一般的处理不会那么简单,有复杂的状态组合(上面的代码并没用nownum,而是用了循环变量i,注意他不是全局的!!!!!).正像zoomq昨天说的0731a的testserver在queue满的时候前面对message的处理就被抛弃了,但在这个生成器版本,先前对message的处理没有被抛弃.
>>
>>个人觉得这个生成器版本还是不够完美,异步传输还是应该以线程为基础进行.下一个版本可能是基于生成器的简单线程:)
>>
>>说得不是很明白,我不清楚大家对什么地方有疑问.
>>
>>
>>===== 2004-08-01 00:33:08 您在来信中写道:=======
>>
>>>细说说,为什么说是生成器版的呢?
>>>
>>>On Sat, 31 Jul 2004 23:22:53 +0800, hoxide <hoxide_dirac at yahoo.com.cn> wrote:
>>>> python-chinese,您好!
>>>>
>>>> 为什么要用生成器,现在的testserver的执行流程只依赖于nownum,而事实上通常的服务要依赖于整个运行流程.另外这样的写法可将窗口部分的代码抽出.
>>>>
>>>> 致
>>>> 礼!
>>>>
>>>> hoxide
>>>> hoxide_dirac at yahoo.com.cn
>>>> 2004-07-31
>>>>
>>>>
>>>>
>>>
>>>
>>>--
>>>HD(燃烧中的火)
>>>我工作我快乐,我勤奋我收获。请与我一起快乐,与我一起收获。
>>>_______________________________________________
>>>python-chinese list
>>>python-chinese at lists.python.cn
>>>http://python.cn/mailman/listinfo/python-chinese
>>>
>>
>>= = = = = = = = = = = = = = = = = = = =
>>
>>
>> 致
>>礼!
>>
>>
>> hoxide
>> hoxide_dirac at yahoo.com.cn
>> 2004-08-01
>>
>>_______________________________________________
>>python-chinese list
>>python-chinese at lists.python.cn
>>http://python.cn/mailman/listinfo/python-chinese
>>
>
>= = = = = = = = = = = = = = = = = = = =
>
>
> 致
>礼!
>
>
> limodou
> chatme at 263.net
> 2004-08-01
>
>_______________________________________________
>python-chinese list
>python-chinese at lists.python.cn
>http://python.cn/mailman/listinfo/python-chinese
>
= = = = = = = = = = = = = = = = = = = =
致
礼!
hoxide
hoxide_dirac at yahoo.com.cn
2004-08-01
2004年08月01日 星期日 14:54
hoxide,您好!
其实真正的数据发送是由客户端做的,我们可以把连接、发送数据等进行封装由客户端来调用。这样由客户端去组织数据,而我们的协议处理只是一个被调用方就行了。因为这只是一个测试程序,还不是真正的应用,因此可能就不讲究了。真正做成客户端,可能程序都要改了。既然我们不想发送太快,queue完全可以采用阻塞方式来处理。
======= 2004-08-01 14:31:17 您在来信中写道:=======
>limodou,您好!
>
> 这点我直到但是程序还是依赖一个全局变量,对于复杂的情况,这种用法是不好的,首先明显得会带来名字空间的污染,其次如果程序执行的上下文关系复杂,那么也就不是几个全局变量能轻松解决的.
>
>
>======= 2004-08-01 14:07:21 您在来信中写道:=======
>
>>hoxide,您好!
>>
>> 其实不丢message也可以,这样不用使用生成器。只要把message生成放到else中就行了。因为那时是可以发送数据的。之所以丢是因为先生成了message,然后才判断是否可以发送,如果不能发送自然就丢了。如果改到可以发送才生成message就不会丢了。
>>
>> while nownum < count:
>> if self.factory.sendQueue.full():
>> self.call = reactor.callLater(0, self.testserver)
>> return
>> else:
>> message = usspmsg.USSPMessage() #*
>> message.setMsgName('mail_counter') #*
>> message.body.setField('uid',str(nownum)) #* 这几行移下来了
>> self.factory.sendQueue.put_nowait(message)
>> nownum += 1
>>
>>======= 2004-08-01 12:19:47 您在来信中写道:=======
>>
>>>HD,您好!
>>>
>>>大家最好先了解一下生成器的有关知识:IBM上的《可爱的 Python:迭代器和简单生成器》: http://www-900.ibm.com/developerWorks/cn/linux/sdk/python/charm-20/index.shtml
>>>
>>>昨天给的代码还有点错误,修改的代码(其实只改了打星号的地方):
>>>
>>> def testserver(self):
>>> """向服务器发的测试报文"""
>>> try:
>>> self.pp.next()
>>> self.call = reactor.callLater(0,self.testserver)
>>> return
>>> except StopIteration:
>>> pass
>>>
>>> def __init__(self):
>>> self.pp=self.sendQQ()
>>> ussp.USSClientQueueProtocol.__init__(self)
>>>
>>> def sendQQ(self):
>>> global nownum
>>> global count
>>> i=1
>>> while i < count:
>>> message = usspmsg.USSPMessage()
>>> message.setMsgName('mail_counter')
>>> message.body.setField('uid',str(i))
>>> while self.factory.sendQueue.full(): #*
>>> yield None #**
>>> self.factory.sendQueue.put_nowait(message)
>>> i += 1
>>> nownum=i
>>> self.disconnect()
>>>
>>>这里真正的处理是在sendQQ这个函数定义的.self.pp是生成器的实例,由__init__()生成,testserver只是调度完成这个处理的函数,而且是和具体的处理独立的,他只是简单得实现了当处理"暂停"后的重新启动.
>>>
>>>真正神奇的地方是打星号的行.他测试sendQueue确定是否能发出message,如果不能就会执行yield None,这时函数就终止在**这行,直到在有.next()方法调用时再从这句开始执行.
>>>这个好处是原来的处理流程可以很顺利得进行.不需要保存中间变量.注意0731a的testserver能正确得发出所有message,是因为恰巧有全局变量nownum完全确定处理的执行状态了.但事事上一般的处理不会那么简单,有复杂的状态组合(上面的代码并没用nownum,而是用了循环变量i,注意他不是全局的!!!!!).正像zoomq昨天说的0731a的testserver在queue满的时候前面对message的处理就被抛弃了,但在这个生成器版本,先前对message的处理没有被抛弃.
>>>
>>>个人觉得这个生成器版本还是不够完美,异步传输还是应该以线程为基础进行.下一个版本可能是基于生成器的简单线程:)
>>>
>>>说得不是很明白,我不清楚大家对什么地方有疑问.
>>>
>>>
>>>===== 2004-08-01 00:33:08 您在来信中写道:=======
>>>
>>>>细说说,为什么说是生成器版的呢?
>>>>
>>>>On Sat, 31 Jul 2004 23:22:53 +0800, hoxide <hoxide_dirac at yahoo.com.cn> wrote:
>>>>> python-chinese,您好!
>>>>>
>>>>> 为什么要用生成器,现在的testserver的执行流程只依赖于nownum,而事实上通常的服务要依赖于整个运行流程.另外这样的写法可将窗口部分的代码抽出.
>>>>>
>>>>> 致
>>>>> 礼!
>>>>>
>>>>> hoxide
>>>>> hoxide_dirac at yahoo.com.cn
>>>>> 2004-07-31
>>>>>
>>>>>
>>>>>
>>>>
>>>>
>>>>--
>>>>HD(燃烧中的火)
>>>>我工作我快乐,我勤奋我收获。请与我一起快乐,与我一起收获。
>>>>_______________________________________________
>>>>python-chinese list
>>>>python-chinese at lists.python.cn
>>>>http://python.cn/mailman/listinfo/python-chinese
>>>>
>>>
>>>= = = = = = = = = = = = = = = = = = = =
>>>
>>>
>>> 致
>>>礼!
>>>
>>>
>>> hoxide
>>> hoxide_dirac at yahoo.com.cn
>>> 2004-08-01
>>>
>>>_______________________________________________
>>>python-chinese list
>>>python-chinese at lists.python.cn
>>>http://python.cn/mailman/listinfo/python-chinese
>>>
>>
>>= = = = = = = = = = = = = = = = = = = =
>>
>>
>> 致
>>礼!
>>
>>
>> limodou
>> chatme at 263.net
>> 2004-08-01
>>
>>_______________________________________________
>>python-chinese list
>>python-chinese at lists.python.cn
>>http://python.cn/mailman/listinfo/python-chinese
>>
>
>= = = = = = = = = = = = = = = = = = = =
>
>
> 致
>礼!
>
>
> hoxide
> hoxide_dirac at yahoo.com.cn
> 2004-08-01
>
>_______________________________________________
>python-chinese list
>python-chinese at lists.python.cn
>http://python.cn/mailman/listinfo/python-chinese
>
= = = = = = = = = = = = = = = = = = = =
致
礼!
limodou
chatme at 263.net
2004-08-01
2004年08月01日 星期日 15:28
limodou,您好!
开始我们也尝试过用queue的阻塞处理,但这样就阻塞了主线程,连recive都不行.
这个问题的根本解决方案还是用线程,我只是提供一种类似的东西("轻便线程"http://www-900.ibm.com/developerWorks/cn/linux/sdk/python/)
另外我觉得应该建一个多连接的测试程序,而不只是一个连接多请求的测试程序.
而窗口应该放在服务端比较好一点
======= 2004-08-01 14:54:55 您在来信中写道:=======
>hoxide,您好!
>
> 其实真正的数据发送是由客户端做的,我们可以把连接、发送数据等进行封装由客户端来调用。这样由客户端去组织数据,而我们的协议处理只是一个被调用方就行了。因为这只是一个测试程序,还不是真正的应用,因此可能就不讲究了。真正做成客户端,可能程序都要改了。既然我们不想发送太快,queue完全可以采用阻塞方式来处理。
>
>======= 2004-08-01 14:31:17 您在来信中写道:=======
>
>>limodou,您好!
>>
>> 这点我直到但是程序还是依赖一个全局变量,对于复杂的情况,这种用法是不好的,首先明显得会带来名字空间的污染,其次如果程序执行的上下文关系复杂,那么也就不是几个全局变量能轻松解决的.
>>
>>
>>======= 2004-08-01 14:07:21 您在来信中写道:=======
>>
>>>hoxide,您好!
>>>
>>> 其实不丢message也可以,这样不用使用生成器。只要把message生成放到else中就行了。因为那时是可以发送数据的。之所以丢是因为先生成了message,然后才判断是否可以发送,如果不能发送自然就丢了。如果改到可以发送才生成message就不会丢了。
>>>
>>> while nownum < count:
>>> if self.factory.sendQueue.full():
>>> self.call = reactor.callLater(0, self.testserver)
>>> return
>>> else:
>>> message = usspmsg.USSPMessage() #*
>>> message.setMsgName('mail_counter') #*
>>> message.body.setField('uid',str(nownum)) #* 这几行移下来了
>>> self.factory.sendQueue.put_nowait(message)
>>> nownum += 1
>>>
>>>======= 2004-08-01 12:19:47 您在来信中写道:=======
>>>
>>>>HD,您好!
>>>>
>>>>大家最好先了解一下生成器的有关知识:IBM上的《可爱的 Python:迭代器和简单生成器》: http://www-900.ibm.com/developerWorks/cn/linux/sdk/python/charm-20/index.shtml
>>>>
>>>>昨天给的代码还有点错误,修改的代码(其实只改了打星号的地方):
>>>>
>>>> def testserver(self):
>>>> """向服务器发的测试报文"""
>>>> try:
>>>> self.pp.next()
>>>> self.call = reactor.callLater(0,self.testserver)
>>>> return
>>>> except StopIteration:
>>>> pass
>>>>
>>>> def __init__(self):
>>>> self.pp=self.sendQQ()
>>>> ussp.USSClientQueueProtocol.__init__(self)
>>>>
>>>> def sendQQ(self):
>>>> global nownum
>>>> global count
>>>> i=1
>>>> while i < count:
>>>> message = usspmsg.USSPMessage()
>>>> message.setMsgName('mail_counter')
>>>> message.body.setField('uid',str(i))
>>>> while self.factory.sendQueue.full(): #*
>>>> yield None #**
>>>> self.factory.sendQueue.put_nowait(message)
>>>> i += 1
>>>> nownum=i
>>>> self.disconnect()
>>>>
>>>>这里真正的处理是在sendQQ这个函数定义的.self.pp是生成器的实例,由__init__()生成,testserver只是调度完成这个处理的函数,而且是和具体的处理独立的,他只是简单得实现了当处理"暂停"后的重新启动.
>>>>
>>>>真正神奇的地方是打星号的行.他测试sendQueue确定是否能发出message,如果不能就会执行yield None,这时函数就终止在**这行,直到在有.next()方法调用时再从这句开始执行.
>>>>这个好处是原来的处理流程可以很顺利得进行.不需要保存中间变量.注意0731a的testserver能正确得发出所有message,是因为恰巧有全局变量nownum完全确定处理的执行状态了.但事事上一般的处理不会那么简单,有复杂的状态组合(上面的代码并没用nownum,而是用了循环变量i,注意他不是全局的!!!!!).正像zoomq昨天说的0731a的testserver在queue满的时候前面对message的处理就被抛弃了,但在这个生成器版本,先前对message的处理没有被抛弃.
>>>>
>>>>个人觉得这个生成器版本还是不够完美,异步传输还是应该以线程为基础进行.下一个版本可能是基于生成器的简单线程:)
>>>>
>>>>说得不是很明白,我不清楚大家对什么地方有疑问.
>>>>
>>>>
>>>>===== 2004-08-01 00:33:08 您在来信中写道:=======
>>>>
>>>>>细说说,为什么说是生成器版的呢?
>>>>>
>>>>>On Sat, 31 Jul 2004 23:22:53 +0800, hoxide <hoxide_dirac at yahoo.com.cn> wrote:
>>>>>> python-chinese,您好!
>>>>>>
>>>>>> 为什么要用生成器,现在的testserver的执行流程只依赖于nownum,而事实上通常的服务要依赖于整个运行流程.另外这样的写法可将窗口部分的代码抽出.
>>>>>>
>>>>>> 致
>>>>>> 礼!
>>>>>>
>>>>>> hoxide
>>>>>> hoxide_dirac at yahoo.com.cn
>>>>>> 2004-07-31
>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>>--
>>>>>HD(燃烧中的火)
>>>>>我工作我快乐,我勤奋我收获。请与我一起快乐,与我一起收获。
>>>>>_______________________________________________
>>>>>python-chinese list
>>>>>python-chinese at lists.python.cn
>>>>>http://python.cn/mailman/listinfo/python-chinese
>>>>>
>>>>
>>>>= = = = = = = = = = = = = = = = = = = =
>>>>
>>>>
>>>> 致
>>>>礼!
>>>>
>>>>
>>>> hoxide
>>>> hoxide_dirac at yahoo.com.cn
>>>> 2004-08-01
>>>>
>>>>_______________________________________________
>>>>python-chinese list
>>>>python-chinese at lists.python.cn
>>>>http://python.cn/mailman/listinfo/python-chinese
>>>>
>>>
>>>= = = = = = = = = = = = = = = = = = = =
>>>
>>>
>>> 致
>>>礼!
>>>
>>>
>>> limodou
>>> chatme at 263.net
>>> 2004-08-01
>>>
>>>_______________________________________________
>>>python-chinese list
>>>python-chinese at lists.python.cn
>>>http://python.cn/mailman/listinfo/python-chinese
>>>
>>
>>= = = = = = = = = = = = = = = = = = = =
>>
>>
>> 致
>>礼!
>>
>>
>> hoxide
>> hoxide_dirac at yahoo.com.cn
>> 2004-08-01
>>
>>_______________________________________________
>>python-chinese list
>>python-chinese at lists.python.cn
>>http://python.cn/mailman/listinfo/python-chinese
>>
>
>= = = = = = = = = = = = = = = = = = = =
>
>
> 致
>礼!
>
>
> limodou
> chatme at 263.net
> 2004-08-01
>
>_______________________________________________
>python-chinese list
>python-chinese at lists.python.cn
>http://python.cn/mailman/listinfo/python-chinese
>
= = = = = = = = = = = = = = = = = = = =
致
礼!
hoxide
hoxide_dirac at yahoo.com.cn
2004-08-01
2004年08月01日 星期日 15:52
在环境变量里增加PYTHONPATH,并把C:\Python23\Lib\site-packages\ 设置在C:\Program Files\Plone 2\Python\Lib\site-packages\前面,可以解决这个问题。 安装zope后,zope不会修改已经安装的python的设置,但是会用自带的python版本, 而且这些启动选项都是可以设置的,但是plone会对已经安装的python注册表等的值做修改 -----原始邮件----- 发件人: python-chinese-bounces at lists.python.cn [mailto:python-chinese-bounces at lists.python.cn]代表 Liming_Do 发送时间: 2004年7月31日 14:46 收件人: python-chinese at lists.python.cn 主题: 答复: 答复: [python-chinese]ANN:NewEdit 2.4版发布! 我把plone卸载掉,NewEdit就可以运行了, wxPython就会使用python安装路径下site-packages下的版本, 谁知道这是为什么? -----原始邮件----- 发件人: python-chinese-bounces at lists.python.cn [mailto:python-chinese-bounces at lists.python.cn]代表 Liming_Do 发送时间: 2004年7月30日 11:28 收件人: python-chinese at lists.python.cn 主题: 答复: 答复: [python-chinese]ANN:NewEdit 2.4版发布! limodou,您好, 我是安装的unicode版本,wxPythonWIN32-2.5.1.5u-Py23.exe 我以前可以运行NewEdit2.3,但是安装plone2以后, plone2就把wxPython的映射到他自己的v 1.4.2.1 2003/04/02 (C:\Program Files\Plone 2\Python\Lib\site-packages\wxPython) 我的问题是不知道怎么能让python使用我自己的wxPython2.5 ? (C:\Python23\Lib\site-packages\wxPython) -----原始邮件----- 发件人: python-chinese-bounces at lists.python.cn [mailto:python-chinese-bounces at lists.python.cn]代表 limodou 发送时间: 2004年7月30日 11:19 收件人: python-chinese at lists.python.cn 主题: Re: 答复: [python-chinese]ANN:NewEdit 2.4版发布! Liming_Do,您好! 是不是你没有安装unicode版?要unicode版本才可以。 ======= 2004-07-30 08:59:36 您在来信中写道:======= >limodou,您好, > >我运行NewEdit 2.4时,出现信息: >You must install wxPython 2.4 Unicode above and Python 2.3 version. >Please install them first before running NewEdit. > >Press Enter to exit the program ... >可是我安装了wxPython 2.5, >从help()中查看wxPython,发现: >NAME > wxPython > >FILE > c:\program files\plone 2\python\lib\site-packages\wxpython\__init__.py > >DESCRIPTION > #---------------------------------------------------------------------------- > # Name: __init__.py > # Purpose: The presence of this file turns this directory into a > # Python package. > # > # Author: Robin Dunn > # > # Created: 8/8/98 > # RCS-ID: $Id: __init__.py,v 1.4.2.1 2003/04/02 01:49:05 RD Exp $ > # Copyright: (c) 1998 by Total Control Software > # Licence: wxWindows license > #---------------------------------------------------------------------------- >可能是因为我先安装的wxPython的路径被后安装的plone 2替换掉了,我在注册表中没有找到这个选项, >请问,我该怎么把wxPython映射到我自己安装的wxPython(C:\Python23\Lib\site-packages\wxPython)? > >Liming > >-----原始邮件----- >发件人: python-chinese-bounces at lists.python.cn >[mailto:python-chinese-bounces at lists.python.cn]代表 0.706 >发送时间: 2004年7月29日 9:18 >收件人: python-chinese at lists.python.cn >主题: Re: [python-chinese]ANN:NewEdit 2.4版发布! > > >limodou,您好! > > 建议在帮助中加上python manuals的链接. > >======= 2004-07-28 17:15:17 您在来信中写道:======= > >>python-chinese,您好! >> >>下载地址:http://pyrecord.freezope.org/download/newedit_2.4r1.zip/down >> >>新增: >> >>1. 代码片段的导入和导出功能,可以导出或导入某个分类 >>2. 增加打印功能,支持HTML文档的打印 >>3. 增加psyco模块的加速支持,使用此功能要先安装psyco模块 >>4. 增加用户插件的管理功能 >>5. 在参数设置中可以设置新建文件缺省的语法高亮类型 >>6. 增加停止运行Python程序的菜单和工具条按钮 >>7. 运行Python程序时可以接收输入信息 >> >>修改: >> >>1. DDE服务的端口可以在config.ini中指定 >>2. 修改打印帮助文件为全路径,且使用file:///协议 >>3. 修改在文件中查找时,双击结果文件行数跳转总多一行的问题 >>4. 修改当存在混合回车符时,保存文件出错的问题 >> >>有什么问题和建议,欢迎与我交流! >> >> >> 致 >>礼! >> >> >> limodou >> chatme at 263.net >> 2004-07-28 >>_______________________________________________ >>python-chinese list >>python-chinese at lists.python.cn >>http://python.cn/mailman/listinfo/python-chinese >> > >= = = = = = = = = = = = = = = = = = = = > > > 致 >礼! > > > 0.706 > 0.706 at 163.com > 2004-07-29 > >_______________________________________________ >python-chinese list >python-chinese at lists.python.cn >http://python.cn/mailman/listinfo/python-chinese = = = = = = = = = = = = = = = = = = = = 致 礼! limodou chatme at 263.net 2004-07-30 _______________________________________________ python-chinese list python-chinese at lists.python.cn http://python.cn/mailman/listinfo/python-chinese _______________________________________________ python-chinese list python-chinese at lists.python.cn http://python.cn/mailman/listinfo/python-chinese
2004年08月01日 星期日 16:50
hoxide,您好!
的确,整个程序只有一个线程,那么这种异步都通过twisted来完成,的确象queue这种阻塞方式就无法实现了。多线程,多点测试才更符合实际。
======= 2004-08-01 15:28:13 您在来信中写道:=======
>limodou,您好!
>
> 开始我们也尝试过用queue的阻塞处理,但这样就阻塞了主线程,连recive都不行.
>这个问题的根本解决方案还是用线程,我只是提供一种类似的东西("轻便线程"http://www-900.ibm.com/developerWorks/cn/linux/sdk/python/)
>另外我觉得应该建一个多连接的测试程序,而不只是一个连接多请求的测试程序.
>而窗口应该放在服务端比较好一点
>
>======= 2004-08-01 14:54:55 您在来信中写道:=======
>
>>hoxide,您好!
>>
>> 其实真正的数据发送是由客户端做的,我们可以把连接、发送数据等进行封装由客户端来调用。这样由客户端去组织数据,而我们的协议处理只是一个被调用方就行了。因为这只是一个测试程序,还不是真正的应用,因此可能就不讲究了。真正做成客户端,可能程序都要改了。既然我们不想发送太快,queue完全可以采用阻塞方式来处理。
>>
>>======= 2004-08-01 14:31:17 您在来信中写道:=======
>>
>>>limodou,您好!
>>>
>>> 这点我直到但是程序还是依赖一个全局变量,对于复杂的情况,这种用法是不好的,首先明显得会带来名字空间的污染,其次如果程序执行的上下文关系复杂,那么也就不是几个全局变量能轻松解决的.
>>>
>>>
>>>======= 2004-08-01 14:07:21 您在来信中写道:=======
>>>
>>>>hoxide,您好!
>>>>
>>>> 其实不丢message也可以,这样不用使用生成器。只要把message生成放到else中就行了。因为那时是可以发送数据的。之所以丢是因为先生成了message,然后才判断是否可以发送,如果不能发送自然就丢了。如果改到可以发送才生成message就不会丢了。
>>>>
>>>> while nownum < count:
>>>> if self.factory.sendQueue.full():
>>>> self.call = reactor.callLater(0, self.testserver)
>>>> return
>>>> else:
>>>> message = usspmsg.USSPMessage() #*
>>>> message.setMsgName('mail_counter') #*
>>>> message.body.setField('uid',str(nownum)) #* 这几行移下来了
>>>> self.factory.sendQueue.put_nowait(message)
>>>> nownum += 1
>>>>
>>>>======= 2004-08-01 12:19:47 您在来信中写道:=======
>>>>
>>>>>HD,您好!
>>>>>
>>>>>大家最好先了解一下生成器的有关知识:IBM上的《可爱的 Python:迭代器和简单生成器》: http://www-900.ibm.com/developerWorks/cn/linux/sdk/python/charm-20/index.shtml
>>>>>
>>>>>昨天给的代码还有点错误,修改的代码(其实只改了打星号的地方):
>>>>>
>>>>> def testserver(self):
>>>>> """向服务器发的测试报文"""
>>>>> try:
>>>>> self.pp.next()
>>>>> self.call = reactor.callLater(0,self.testserver)
>>>>> return
>>>>> except StopIteration:
>>>>> pass
>>>>>
>>>>> def __init__(self):
>>>>> self.pp=self.sendQQ()
>>>>> ussp.USSClientQueueProtocol.__init__(self)
>>>>>
>>>>> def sendQQ(self):
>>>>> global nownum
>>>>> global count
>>>>> i=1
>>>>> while i < count:
>>>>> message = usspmsg.USSPMessage()
>>>>> message.setMsgName('mail_counter')
>>>>> message.body.setField('uid',str(i))
>>>>> while self.factory.sendQueue.full(): #*
>>>>> yield None #**
>>>>> self.factory.sendQueue.put_nowait(message)
>>>>> i += 1
>>>>> nownum=i
>>>>> self.disconnect()
>>>>>
>>>>>这里真正的处理是在sendQQ这个函数定义的.self.pp是生成器的实例,由__init__()生成,testserver只是调度完成这个处理的函数,而且是和具体的处理独立的,他只是简单得实现了当处理"暂停"后的重新启动.
>>>>>
>>>>>真正神奇的地方是打星号的行.他测试sendQueue确定是否能发出message,如果不能就会执行yield None,这时函数就终止在**这行,直到在有.next()方法调用时再从这句开始执行.
>>>>>这个好处是原来的处理流程可以很顺利得进行.不需要保存中间变量.注意0731a的testserver能正确得发出所有message,是因为恰巧有全局变量nownum完全确定处理的执行状态了.但事事上一般的处理不会那么简单,有复杂的状态组合(上面的代码并没用nownum,而是用了循环变量i,注意他不是全局的!!!!!).正像zoomq昨天说的0731a的testserver在queue满的时候前面对message的处理就被抛弃了,但在这个生成器版本,先前对message的处理没有被抛弃.
>>>>>
>>>>>个人觉得这个生成器版本还是不够完美,异步传输还是应该以线程为基础进行.下一个版本可能是基于生成器的简单线程:)
>>>>>
>>>>>说得不是很明白,我不清楚大家对什么地方有疑问.
>>>>>
>>>>>
>>>>>===== 2004-08-01 00:33:08 您在来信中写道:=======
>>>>>
>>>>>>细说说,为什么说是生成器版的呢?
>>>>>>
>>>>>>On Sat, 31 Jul 2004 23:22:53 +0800, hoxide <hoxide_dirac at yahoo.com.cn> wrote:
>>>>>>> python-chinese,您好!
>>>>>>>
>>>>>>> 为什么要用生成器,现在的testserver的执行流程只依赖于nownum,而事实上通常的服务要依赖于整个运行流程.另外这样的写法可将窗口部分的代码抽出.
>>>>>>>
>>>>>>> 致
>>>>>>> 礼!
>>>>>>>
>>>>>>> hoxide
>>>>>>> hoxide_dirac at yahoo.com.cn
>>>>>>> 2004-07-31
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>
>>>>>>
>>>>>>--
>>>>>>HD(燃烧中的火)
>>>>>>我工作我快乐,我勤奋我收获。请与我一起快乐,与我一起收获。
>>>>>>_______________________________________________
>>>>>>python-chinese list
>>>>>>python-chinese at lists.python.cn
>>>>>>http://python.cn/mailman/listinfo/python-chinese
>>>>>>
>>>>>
>>>>>= = = = = = = = = = = = = = = = = = = =
>>>>>
>>>>>
>>>>> 致
>>>>>礼!
>>>>>
>>>>>
>>>>> hoxide
>>>>> hoxide_dirac at yahoo.com.cn
>>>>> 2004-08-01
>>>>>
>>>>>_______________________________________________
>>>>>python-chinese list
>>>>>python-chinese at lists.python.cn
>>>>>http://python.cn/mailman/listinfo/python-chinese
>>>>>
>>>>
>>>>= = = = = = = = = = = = = = = = = = = =
>>>>
>>>>
>>>> 致
>>>>礼!
>>>>
>>>>
>>>> limodou
>>>> chatme at 263.net
>>>> 2004-08-01
>>>>
>>>>_______________________________________________
>>>>python-chinese list
>>>>python-chinese at lists.python.cn
>>>>http://python.cn/mailman/listinfo/python-chinese
>>>>
>>>
>>>= = = = = = = = = = = = = = = = = = = =
>>>
>>>
>>> 致
>>>礼!
>>>
>>>
>>> hoxide
>>> hoxide_dirac at yahoo.com.cn
>>> 2004-08-01
>>>
>>>_______________________________________________
>>>python-chinese list
>>>python-chinese at lists.python.cn
>>>http://python.cn/mailman/listinfo/python-chinese
>>>
>>
>>= = = = = = = = = = = = = = = = = = = =
>>
>>
>> 致
>>礼!
>>
>>
>> limodou
>> chatme at 263.net
>> 2004-08-01
>>
>>_______________________________________________
>>python-chinese list
>>python-chinese at lists.python.cn
>>http://python.cn/mailman/listinfo/python-chinese
>>
>
>= = = = = = = = = = = = = = = = = = = =
>
>
> 致
>礼!
>
>
> hoxide
> hoxide_dirac at yahoo.com.cn
> 2004-08-01
>
>_______________________________________________
>python-chinese list
>python-chinese at lists.python.cn
>http://python.cn/mailman/listinfo/python-chinese
>
= = = = = = = = = = = = = = = = = = = =
致
礼!
limodou
chatme at 263.net
2004-08-01
2004年08月01日 星期日 16:50
Liming_Do,您好! 现在zope3就完全安装到了python目录下,不再有单独的目录。就解决了这个问题。 ======= 2004-08-01 15:52:43 您在来信中写道:======= >在环境变量里增加PYTHONPATH,并把C:\Python23\Lib\site-packages\ >设置在C:\Program Files\Plone 2\Python\Lib\site-packages\前面,可以解决这个问题。 >安装zope后,zope不会修改已经安装的python的设置,但是会用自带的python版本, >而且这些启动选项都是可以设置的,但是plone会对已经安装的python注册表等的值做修改 > >-----原始邮件----- >发件人: python-chinese-bounces at lists.python.cn >[mailto:python-chinese-bounces at lists.python.cn]代表 Liming_Do >发送时间: 2004年7月31日 14:46 >收件人: python-chinese at lists.python.cn >主题: 答复: 答复: [python-chinese]ANN:NewEdit 2.4版发布! > > >我把plone卸载掉,NewEdit就可以运行了, >wxPython就会使用python安装路径下site-packages下的版本, >谁知道这是为什么? > >-----原始邮件----- >发件人: python-chinese-bounces at lists.python.cn >[mailto:python-chinese-bounces at lists.python.cn]代表 Liming_Do >发送时间: 2004年7月30日 11:28 >收件人: python-chinese at lists.python.cn >主题: 答复: 答复: [python-chinese]ANN:NewEdit 2.4版发布! > > >limodou,您好, >我是安装的unicode版本,wxPythonWIN32-2.5.1.5u-Py23.exe >我以前可以运行NewEdit2.3,但是安装plone2以后, >plone2就把wxPython的映射到他自己的v 1.4.2.1 2003/04/02 (C:\Program Files\Plone 2\Python\Lib\site-packages\wxPython) >我的问题是不知道怎么能让python使用我自己的wxPython2.5 ? (C:\Python23\Lib\site-packages\wxPython) > >-----原始邮件----- >发件人: python-chinese-bounces at lists.python.cn >[mailto:python-chinese-bounces at lists.python.cn]代表 limodou >发送时间: 2004年7月30日 11:19 >收件人: python-chinese at lists.python.cn >主题: Re: 答复: [python-chinese]ANN:NewEdit 2.4版发布! > > >Liming_Do,您好! > > 是不是你没有安装unicode版?要unicode版本才可以。 > >======= 2004-07-30 08:59:36 您在来信中写道:======= > >>limodou,您好, >> >>我运行NewEdit 2.4时,出现信息: >>You must install wxPython 2.4 Unicode above and Python 2.3 version. >>Please install them first before running NewEdit. >> >>Press Enter to exit the program ... >>可是我安装了wxPython 2.5, >>从help()中查看wxPython,发现: >>NAME >> wxPython >> >>FILE >> c:\program files\plone 2\python\lib\site-packages\wxpython\__init__.py >> >>DESCRIPTION >> #---------------------------------------------------------------------------- >> # Name: __init__.py >> # Purpose: The presence of this file turns this directory into a >> # Python package. >> # >> # Author: Robin Dunn >> # >> # Created: 8/8/98 >> # RCS-ID: $Id: __init__.py,v 1.4.2.1 2003/04/02 01:49:05 RD Exp $ >> # Copyright: (c) 1998 by Total Control Software >> # Licence: wxWindows license >> #---------------------------------------------------------------------------- >>可能是因为我先安装的wxPython的路径被后安装的plone 2替换掉了,我在注册表中没有找到这个选项, >>请问,我该怎么把wxPython映射到我自己安装的wxPython(C:\Python23\Lib\site-packages\wxPython)? >> >>Liming >> >>-----原始邮件----- >>发件人: python-chinese-bounces at lists.python.cn >>[mailto:python-chinese-bounces at lists.python.cn]代表 0.706 >>发送时间: 2004年7月29日 9:18 >>收件人: python-chinese at lists.python.cn >>主题: Re: [python-chinese]ANN:NewEdit 2.4版发布! >> >> >>limodou,您好! >> >> 建议在帮助中加上python manuals的链接. >> >>======= 2004-07-28 17:15:17 您在来信中写道:======= >> >>>python-chinese,您好! >>> >>>下载地址:http://pyrecord.freezope.org/download/newedit_2.4r1.zip/down >>> >>>新增: >>> >>>1. 代码片段的导入和导出功能,可以导出或导入某个分类 >>>2. 增加打印功能,支持HTML文档的打印 >>>3. 增加psyco模块的加速支持,使用此功能要先安装psyco模块 >>>4. 增加用户插件的管理功能 >>>5. 在参数设置中可以设置新建文件缺省的语法高亮类型 >>>6. 增加停止运行Python程序的菜单和工具条按钮 >>>7. 运行Python程序时可以接收输入信息 >>> >>>修改: >>> >>>1. DDE服务的端口可以在config.ini中指定 >>>2. 修改打印帮助文件为全路径,且使用file:///协议 >>>3. 修改在文件中查找时,双击结果文件行数跳转总多一行的问题 >>>4. 修改当存在混合回车符时,保存文件出错的问题 >>> >>>有什么问题和建议,欢迎与我交流! >>> >>> >>> 致 >>>礼! >>> >>> >>> limodou >>> chatme at 263.net >>> 2004-07-28 >>>_______________________________________________ >>>python-chinese list >>>python-chinese at lists.python.cn >>>http://python.cn/mailman/listinfo/python-chinese >>> >> >>= = = = = = = = = = = = = = = = = = = = >> >> >> 致 >>礼! >> >> >> 0.706 >> 0.706 at 163.com >> 2004-07-29 >> >>_______________________________________________ >>python-chinese list >>python-chinese at lists.python.cn >>http://python.cn/mailman/listinfo/python-chinese > >= = = = = = = = = = = = = = = = = = = = > > > 致 >礼! > > > limodou > chatme at 263.net > 2004-07-30 > >_______________________________________________ >python-chinese list >python-chinese at lists.python.cn >http://python.cn/mailman/listinfo/python-chinese >_______________________________________________ >python-chinese list >python-chinese at lists.python.cn >http://python.cn/mailman/listinfo/python-chinese >_______________________________________________ >python-chinese list >python-chinese at lists.python.cn >http://python.cn/mailman/listinfo/python-chinese = = = = = = = = = = = = = = = = = = = = 致 礼! limodou chatme at 263.net 2004-08-01
Zeuux © 2025
京ICP备05028076号