社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

python-yield和raise异常

Sharvari Gc • 5 年前 • 1598 次点击  

我正在尝试编写一个函数,该函数生成两个变量,并根据条件引发异常。 下面是一个简单的例子:

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并引发异常。 我需要它在这个函数内部产生一个异常,这样其他模块就可以直接使用这个函数而不需要额外的代码。 如果收益率声明不是一个好主意,那么什么是?

尝试- [_ for _ in func()] 但是var1和var2的值并没有像预期的那样从收益率上改变。
尝试- var1, var2 = next(func()) 这会产生,但不会引发异常。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/43382
 
1598 次点击  
文章 [ 2 ]  |  最新文章 5 年前
Dinesh
Reply   •   1 楼
Dinesh    6 年前

您需要迭代以执行异常。遵循最少的代码确实会引发异常。

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()) 正如您在编辑中提到的,每次调用时都会创建新的生成器 下一个(函数()) . 相反,如上所示,先实例化它,然后调用多次。

社区wiki作为相关问题,无法在评论中添加此内容。

Paritosh Singh
Reply   •   2 楼
Paritosh Singh    6 年前

好吧,那么先解决几个问题。
1。解包对单个值不起作用,它试图用尽iterable并立即解包所有内容。

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
  1. 最后但并非最不重要的是,确保你真的需要收益率,就目前的情况来看,我怀疑这个函数既难以阅读,也可能值得拆分成更小的模块。我强烈建议您再看一眼代码,如果可能的话,可以考虑进一步破坏它。