为什么发电机不执行直到第一次产出?

你好!
首先有点上下文.
昨天我花了很多时间在
我们已经开发的相当苗条的数据库抽象层:
,------
| def selectcolumn(self,table,column,where = {},order_by = [],group_by = []):
| """执行SQL选择查询返回单列
|
|该列作为列表返回.如果有例外
|结果不是单列."""
| query = build_select(表,[列],where,order_by,group_by)
|结果= dbresult(self.rawquery(QUERY))
|如果结果.Colcount!= 1:
|提高QueryError("查询必须返回一列",查询)
|对于result.fetchallrowsaslist():
|屈服行[0]
`------
我只是将该方法重写为发电机,而不是返回
结果列表.然后以下测试失败:
,------
| DEF testSelectColumnMultipliplecolumns(自我):
| res = self.fdb.selectcolumn('db3ut1',['c1','c2'],
| {'c1':( 1,2)},order_by ='c1')
| self.assertraises(db3.queryerror,self.fdb.selectcolumn,
| 'db3ut1',['c1','c2'],{'c1':( 1,2)},order_by ='c1')
`------
我希望由于结果而引起QueryError.
受到侵犯的约束(以前是这样),但这不是
案子.直到我从中获得第一个结果,
发电机.
现在要重点.当运行发电机函数时,立即
返回发电机,并且不会在发电机内运行任何代码.
直到发电机.next()才称为发电机内部的任何代码
执行,提供传统的懒惰评估语义.为什么不
发电机遵循Python和
立即执行直到首先产生之前?
给发电机的特殊情况语义没有充分的理由是真的
坏主意,所以我很好奇是否有充分的理由
这边走.使用当前的语义,这意味着错误可能会弹出
意外的时间,而不是代码快速失败.
马丁

# 回答1


2008年5月7日,星期三,上​​午2:29,马丁·桑德·克里斯滕森(Martin Sand Christensen) 懒惰评估不是用来替换列表的全部要点
迭代器?除此之外,当
实例化会使发电机的第一次迭代不一致
剩下的迭代.考虑一下这个人为的
例子:
def printing_iter(Quatt):
对于物品中的物品:
打印项目
产量项目
显然,这里的想法是创建一个包裹另一个的生成器
迭代器并打印每个项目,以产生它.但是使用你的
建议,这将在当时打印第一项
创建发电机,而不是在第一项实际上是
迭代了.
如果您真的想要一个表现方式的发电机,我
建议这样做这样的事情:
Def mygenerator(args):
aggy_setup_code()
Def Generator():
对于实际_GE中的项目 nerator_loop():
产量项目
返回生成器()
# 回答2


马丁·桑德·克里斯滕森(Martin Sand Christensen)
立即地
发电机.
您的意思是您希望发电机的语义是当您
创建它们,或者每次您调用Next()它们运行直到达到产量
然后(初始运行除外)返回所产生的结果
之前的时间?实施它非常容易,但是可能有点
对用户感到困惑.
def greedgenerator(*args,** kw):
def delayed():
it = iter(fn(*args,** kw))
尝试:
res = it.next()
除了停止:
没有产生
返回
没有产生
在其中的价值:
产量res
res =值
产量res
it = delayed()
it.next()
把它返还
返回贪婪
def mygen(n):
对于(n)范围内的我:
打印i
产量i
0
1
2
[0,1,2]
[]
现在尝试:
对于getCommandSfromuser()中的命令:
打印"该命令的结果",执行(命令)
哪里是getCommandsfromuser是一个贪婪的发电机,从stdin读取,
并了解为什么发电机无法那样工作.
# 回答3


>>>>" ian" == ian Kelly Ianis不是懒惰的评估,这是更换列表的全部要点
伊恩(Ian)是迭代器吗?除此之外,当
伊恩斯坦化将使发电机的第一次迭代
伊曼奇与剩余的迭代息息相关.
那不是我的主意,尽管那可能还没有遇到
显然足够了.我希望发电机立即运行直到正确
在第一个收益率之前
第一个产量.
我的反对是发电机_by default_有不同的语义
比其余的语言.懒惰评估作为一个概念非常适合
它可以提供的所有好处,但是,正如我所说明的那样,严格懒惰
评估语义有时可能会令人惊讶,并导致
如果您不断不断承担
考虑的差异.在这方面,在我看来我的建议
将是一个改进.我没有任何语言专家,
不过,我很可能会错过更大的一部分
使事情变得很明显.
至于代码稍微更改发电机的语义,这不是
真正解决了我看到的问题:如果您要应用此类代码
对于您的发电机,您可能会完全做到这一点,因为您
意识到语义的差异,您不会
对此感到惊讶.您可能仍然想更改语义,但是
与我的观点无关的原因.
马丁
# 回答4


>>>>" Duncan" == Duncan Booth [...]
Duncannow尝试:
邓肯>
duncan在getCommandsfromuser()中命令:
邓肯打印"该命令的结果",执行(命令)
邓肯>
duncanwhere getCommandsfromuser是一种贪婪的发电机,从stdin读取,
邓肯南(Duncanand)明白为什么发电机无法那样工作.
除非发电机没有,我看不到问题 定义在哪里
要使用.在其他类似的输入约束用例中,例如
发电机在我的原始帖子中进行查询结果设置,我看到
甚至更少的问题.也许我只是愚蠢,你需要拼写
为我出去. :-)
马丁
# 回答5


马丁·桑德·克里斯滕森(Martin Sand Christensen)
[...]
Duncannow尝试:
邓肯>
duncan在getCommandsfromuser()中命令:
邓肯打印"该命令的结果",
执行(命令)Duncan>
duncanwhere getCommandsfromuser是一种贪婪的发电机,读取
邓肯南德(Duncanand)从斯丁(Stdin)看为什么发电机不这样做.
除非生成器未定义在哪里,否则我不会看到问题
要使用.在其他类似的输入约束用例中,例如
发电机在我的原始帖子中进行查询结果设置,我看到
甚至更少的问题.也许我只是愚蠢,你需要拼写
为我出去. :-)
它这样做:
def getCommandSfromuser():
而真:
产生RAW_INPUT('命令?')
打印"那是命令",cmd
命令?你好
命令?再见
那是命令你好
命令?wtf
那是命令再见
命令?
Trackback(最近的最新电话):
文件" ",第1行,在
对于getCommandSfromuser()中的CMD:
文件" ",第11行,延迟
在其中的价值:
文件" ",第4行,在getCommandsfromuser中
产生RAW_INPUT('命令?')
键盘线路
# 回答6


邓肯·布斯(Duncan Booth)写道:
def getCommandSfromuser():
而真:
产生RAW_INPUT('命令?')
打印"那是命令",cmd
命令?你好
命令?再见
那是命令你好
命令?wtf
那是命令再见
命令?

不在这里..
在[7]中:def getCommandSfromuser():
而真:
产生RAW_INPUT('命令?')
...:
...:
在[10]中:对于getCommandsfromuser()中的CMD:打印"那是命令",cmd
....::
命令?嗨
那是命令嗨
命令?那里
那是命令
命令?wuwuwuw
那是命令wuwuwuw
命令?

# 回答7


Marco Mariani写道:
哦,对不起,我显然没有看到所有的@greedy装饰师
引用水平.
无论如何,这个想法对我来说没有多大意义:)
# 回答8


marco mariani def getCommandSfromuser():true:forad raw_input('命令?')
打印"那是命令",cmd
命令?hellocommand?再见,命令是hellocommand吗?

不在这里..
在[7]中:def getCommandSfromuser():
而真:
产生RAW_INPUT('命令?')
...:
...:
在[10]中:对于getCommandsfromuser()中的CMD:打印"那是命令",
CMD
也许如果您复制了我的所有代码(包括
它的全部要点)...

# 回答9


邓肯·布斯(Duncan Booth)写道:
当然,我错过了重点. python的符号成为引用级别和
混乱消息.
无论如何,我会讨厌在开始之前开始执行发电机
迭代它.特别是当发电机传递时.
当前的行为使 完美的感觉.
# 回答10


5月7日,7:37*AM,Marco Mariani 当然,我错过了重点. python的符号成为引用级别和
混乱消息.
无论如何,我会讨厌在开始之前开始执行发电机
迭代它.特别是当发电机传递时.
当前的行为是完全合理的.
问题:
...打印0
...而1:
...产量1
...
0
1
1
1
这可能适合该法案:
... H.Next()
...返回h
...
0
1
1
1
但是,由于dropfirst删除了一个值,两个呼叫者和 - cally都有
指定一个/例外.持有发电机更好"
掉了",然后您握住'Next'固有地造成副作用.@Greedy
(从前)释放呼叫者的责任/义务.
没有铅可以跟随什么?
这些定义可能会在"世代"上更坚固地倾斜
"下一步":发电机本质上不会引起副作用.
或持有,首先也不例外:
...打印0
...屈服特殊
...而1:
...产量1
...
0
<对象在0x00980470>
1
1
1
# 回答11


现在要重点.当运行发电机函数时,立即
发电机的语义非常清晰:在.next()上,运行直到下一个
达到收益率,然后返回屈服值.加上当然
处理止损.
您的场景将引入第一次跑步的特殊案例,使其成为
保持额外状态的必要条件(可能引入GC发出
在途中),只是为了它.并违反了发电机的懒惰
全部.想到这样的情况:
def g():
而真:
屈服时间.时间()
显然,您想在被调用的.next()时产生时间.
没有很久以前存储的东西.如果有任何设置发电机的设置
应立即完成,这很容易:
def g():
first_result = time.time()
def _g():
产生first_result
而真:
屈服时间.时间()
返回 _()
diez
# 回答12


马丁·桑德·克里斯滕森(Martin Sand Christensen)写道:
一个很好的例子,说明这种行为会击败某些目的
可以在此惊人的PDF演示文稿中找到发电机:http://www.dabeaz.com/generators/generators.pdf
最肯定的是,他们确实有充分的理由.考虑PDF中的案例
我刚才提到.建筑发电机,这些发电机在其他的输出上工作
发电机允许组装整个行为管道.非常
强大的功能,如果发电机拥有
您描述的语义.
如果您希望发电机按照您的建议表现,那么
X在Blah方法中的常规方法可能是更好的方法.
我随时都可以使用发电机来迭代某些东西
在记忆或CPU方面,这可能是昂贵的成本
一次全部.
# 回答13


5月7日,4:51*下午,迈克尔·托里(Michael Torrie) 可以在此惊人的PDF演示文稿中找到发电机:http://www.dabeaz.com/generators/generators.pdf
最肯定的是,他们确实有充分的理由. *考虑PDF中的案例
我刚才提到. *构建用于其他输出的发电机
发电机允许组装整个行为管道. *非常
强大的功能,如果发电机拥有
您描述的语义.
如果您希望发电机按照您的建议表现,那么
X在Blah方法中的常规方法可能是更好的方法.
我随时都可以使用发电机来迭代某些东西
在记忆或CPU方面,这可能是昂贵的成本
一次全部.
您可以在程序中写的集中量
(固定时间)有限.听起来@greedy是
走的路.召回实施可能在
未来,但功能不是很好吗?有环节
书面?有什么不同吗?
@Greedy的命名也受到质疑.我的卑鄙肌肉
@early vs. @late; @yiveprior; @DropFirst; @cooperative.
thesaurus.com添加@Ahead vs. @behind.

标签: python

添加新评论