我正在用Python学习,yield发现这yield不仅是生成器输出返回值的方式,而且是将值放入生成器的方法.例如以下代码
def f():
print (yield),
print 0,
print (yield),
print 1
g = f()
g.send(None)
g.send('x')
g.send('y')
Run Code Online (Sandbox Code Playgroud)
在全球范围内,它send是值'x','y'发电机,因此f它将输出x 0 y 1.但我无法理解
yield秒但3 send秒.为什么要None在第一时间发送?StopIteration最后抛出一个send.有什么方法可以避免这种异常吗?有人可以解释一下吗?提前致谢.
该yield关键字的文档说:
yield关键字向编译器发出信号,表明它出现的方法是迭代器块.
我yield在任何迭代器块之外使用关键字遇到过代码.这是否应被视为编程错误或是否正常?
编辑对不起忘了发表我的代码:
int yield = previousVal/actualVal;
return yield; // Should this be allowed!!!???
Run Code Online (Sandbox Code Playgroud)
谢谢.
这是一个奇怪的问题,所以我将解释:
我有一个像这样的生成器,它充当 IRC 服务器的生成器前端:
def irc_iter(): # not the real code, simplified
msgs = get_msgs()
for msg in msgs:
if is_ping(msg):
pong()
else:
to_send = yield msg
for s in to_send:
send(s)
Run Code Online (Sandbox Code Playgroud)
从理论上讲,这应该允许我做一些很酷的事情,例如:
server = connect()
for line in server:
if should_respond(line):
server.send('WOW SUCH MESSAGE')
Run Code Online (Sandbox Code Playgroud)
但是,有一个问题:也会generator.send 产生下一个值。这意味着这server.send也给了我下一条消息......我更愿意像所有其他消息一样处理它,产生为line.
我知道我可以用一种丑陋的方式来解决这个问题,在接收到发送后只产生一个垃圾值,但我试图保持我的代码优雅,但恰恰相反。有没有办法告诉生成器我还不需要新值?
谢谢。
我是Python和编程的新手.对于新程序员来说,生成器有点太复杂了.这是我在Python中关于生成器函数的理论:
任何包含yield语句的函数都将返回一个生成器对象
生成器对象是堆栈包含状态
每次调用.next方法时,Python都会提取函数的状态,当它找到另一个yield语句时,它会再次绑定状态并删除先前的状态:
例:
[
[state1] # Stack contains states and states contain info about the function
[state2] # State1 will be deleted when python finds the other yield?
]
Run Code Online (Sandbox Code Playgroud)
这当然可能就像地球上最愚蠢的理论,但请原谅我,我只是编码中的新词.
我的问题:
Python内部用于存储状态的内容是什么?
yield如果存在,语句是否会向堆栈添加状态?
什么产量在内部产生?我理解yield会创建一个生成器对象,但是,我想知道生成器对象包含什么使它们工作?它们只是一个堆栈/状态列表,我们使用.next方法来提取每个状态,Python会自动调用具有索引状态的函数吗?
在Python中,我多次看到yield用于创建生成器的函数.这个和print函数在技术上都执行方法的操作,因为它们返回一个值.但是,在从Python 2更改为Python 3期间,print函数获得了括号,就像普通的方法调用一样,但是yield保持不变.此外,yield保留关键字的颜色为淡黄色,而print保留方法的颜色为紫色.为什么yield不将这种方法视为一种方法,并且不使用括号语法?
(同样,为什么return还缺少括号?)
让我添加一些东西,yield和continue也没有在许多其他语言中给出括号.我只是想知道是什么让它与保留不同.还有许多其他保留方法可以获得括号.
我试图通过构建一个生成器来理解yield语句的行为,该生成器的行为与“枚举”内置函数类似,但我发现根据我如何迭代它而出现不一致。
def enumerate(sequence, start=0):
n = start
for elem in sequence:
print("Before the 'yield' statement in the generator, n = {}".format(n))
yield n, elem
n += 1
print("After the 'yield' statement in the generator, n = {}".format(n))
Run Code Online (Sandbox Code Playgroud)
我对生成器的理解是,一旦到达yield 语句,代码的执行就会停止,并返回一个值。这与我通过下面的脚本得到的结果相匹配。
a = 'foo'
b = enumerate(a)
n1,v1 = next(b)
print('n1 = {}, v1 = {}\n'.format(n1,v1))
n2,v2 = next(b)
print('n2 = {}, v2 = {}'.format(n2,v2))
Run Code Online (Sandbox Code Playgroud)
在这种情况下,生成器似乎完全停止在yield语句处,并在n+=1处用第二个“next”语句恢复:
Before the 'yield' statement in the generator, n = 0
n1 = 0, v1 = f …Run Code Online (Sandbox Code Playgroud) 编译器抱怨resultingThing在下面的代码中被分配之前正在使用.
private IEnumerable<IThing> FindThings(dynamic spec)
{
if (spec == null)
yield break;
IThing resultingThing;
if (spec.Something > 0 && dictionary.TryGetValue(spec.Something, out resultingThing))
yield return resultingThing;
else
// ...
}
Run Code Online (Sandbox Code Playgroud)
为什么声称这个?
我已经尝试了一个不同版本的方法,其中没有产量使用(例如,只是return IEnumerable<IThing>)但是使用动态参数,我尝试了一种不传递动态的方法版本(即我们在以前版本的C#).这些编译.
我在Scala中有一个DateTime和TimeSpan类(假设<和+运算符可以正常工作).我正在尝试定义一个'范围'函数,它采用开始/停止时间和步进的时间跨度.在C#中,我会以收益率来做这件事,我想我应该能够在Scala中做同样的事情......除了我得到一个奇怪的错误.
在'收益率'线上,我得到"非法开始陈述".
def dateRange(from : DateTime, to : DateTime, step : TimeSpan) =
{
// not sure what the list'y way of doing this is
var t = from
while(t < to)
{
yield t; // error: illegal start of statement
t = t + step
}
}
Run Code Online (Sandbox Code Playgroud)
看看这段代码,我很好奇两件事:1)我做错了什么?2)编写的代码非常必要(使用var t等).在Scala中以更快的速度执行此操作的功能是什么?
谢谢!
我需要一次生成多个结果,而不是一次生成数组中的所有结果.
如何在Matlab中使用像Python一样的语法生成器?
yield-keyword ×10
python ×6
generator ×5
yield ×3
c# ×2
python-3.x ×2
.net ×1
c#-4.0 ×1
coroutine ×1
dynamic ×1
loops ×1
matlab ×1
python-2.7 ×1
scala ×1
yield-return ×1