我正在尝试编写一个产生两个变量并且还根据条件引发异常的函数。 这是一个最小的示例:
def func():
var1 = 0
var2 = 1
yield var1, var2
if not var1 > var2:
raise Exception(var1,var2)
var1, var2 = (1,1)
var1,var2 = func()
此结构当前不产生var1,var2并引发异常。 我需要它来产生并在此函数本身内引发异常,以便其他模块可以直接使用此函数而无需其他代码。 如果yield语句不是一个好主意,那是什么?
已尝试-[_ for _ in func()]
,但var1和var2的值没有像产量期望的那样变化。
已尝试-var1, var2 = next(func())
会产生但不会引发异常。
答案 0 :(得分:0)
您需要迭代执行该异常。遵循最少的代码确实会引发异常。
def func(a,b):
#..do something...
yield a, b
if a!=b:
raise Exception(a,b)
[_ for _ in func(1,2)]
这与No 'print' output when using yield?
有关特别是从一个答案那里引述"Calling a generator function as in testFunc(1) simply creates a generator instance; it does not run the body of the code."
编辑 以下说明了解决方案。这也是来自上面引用的线程。
def func(a,b):
#..do something...
for i in range(10):
a+=1
yield a, b
if a>3:
raise Exception(a,b)
gen=func(1,2)
next(gen) # returns (2,2)
next(gen) # returns (3,2)
next(gen) # return (4,2)
next(gen) # returns Exception. As expected
如果您像在编辑中提到的那样执行next(func())
,则每次调用next(func())
都会创建一个新的生成器。而是如上所述,先实例化它,然后调用几次。
社区Wiki作为相关问题,因此无法在评论中添加。
答案 1 :(得分:0)
好,所以首先要解决几个问题。
1.拆包不适用于单个值,它试图耗尽可迭代的对象并立即解包所有内容。
def func():
# ..do something...
yield 1, 2
yield 3
yield 4
a, b = func() #ValueError: too many values to unpack (expected 2)
a, b, c, d = func() #ValueError: not enough values to unpack (expected 4, got 3)
a, b, c = func() #Works
print(a) # (1,2)
2.Yield会在遇到任何地方停止执行。
def func():
yield 1, 2
raise Exception
func_gen = func()
print(func_gen) #<generator object func at 0x000000ACB5A5EBF8>
val1, val2 = next(func_gen) #assigns values
next(func_gen) #raises exception only on next pass
3。必须做出妥协(这应该回答您的要求)
func_gen = func()
print(func_gen) #<generator object func at 0x000000ACB5A5EBF8>
for _ in func_gen:
res = _
#raises Exception but res = (1, 2)
4。建议(请不要使用异常,这实际上是if条件的工作)
def func():
var1 = 0
var2 = 1
flag = not var1 > var2
yield var1, var2, flag #just add a flag during yield
#instead of your exception
# if not var1 > var2:
# raise Exception(var1,var2)
#stuff
yield 'something else'
func_gen = func()
print(func_gen) #<generator object func at 0x000000ACB5A5EBF8>
for _ in func_gen:
res = _
*values, flag = res
if flag:
break
var1,var2 = values #0, 1