我看到了许多生成器函数的示例,但是我想知道如何为类编写生成器。可以说,我想写斐波那契数列作为一个类。
class Fib:
def __init__(self):
self.a, self.b = 0, 1
def __next__(self):
yield self.a
self.a, self.b = self.b, self.a+self.b
f = Fib()
for i in range(3):
print(next(f))
输出:
<generator object __next__ at 0x000000000A3E4F68>
<generator object __next__ at 0x000000000A3E4F68>
<generator object __next__ at 0x000000000A3E4F68>
为什么值self.a
没有打印出来?另外,我该如何unittest
为发电机编写代码?
您快要写完 Iterator
类了(我在答案末尾显示了Generator),但是__next__
每次使用调用对象时都会被调用next
,并返回一个generator对象。相反,要使您的代码以最少的更改和最少的代码行工作,请使用__iter__
,这使您的类实例化为
可迭代的 (从技术上讲,它不是 生成器 ):
class Fib:
def __init__(self):
self.a, self.b = 0, 1
def __iter__(self):
while True:
yield self.a
self.a, self.b = self.b, self.a+self.b
当我们向传递一个iterable时iter()
,它为我们提供了一个 迭代器 :
>>> f = iter(Fib())
>>> for i in range(3):
... print(next(f))
...
0
1
1
为了使类本身成为 迭代器 ,它确实需要一个__next__
:
class Fib:
def __init__(self):
self.a, self.b = 0, 1
def __next__(self):
return_value = self.a
self.a, self.b = self.b, self.a+self.b
return return_value
def __iter__(self):
return self
现在,由于iter
只返回实例本身,因此我们无需调用它:
>>> f = Fib()
>>> for i in range(3):
... print(next(f))
...
0
1
1
为什么值self.a没有得到打印?
这是带有我的注释的原始代码:
class Fib:
def __init__(self):
self.a, self.b = 0, 1
def __next__(self):
yield self.a # yield makes .__next__() return a generator!
self.a, self.b = self.b, self.a+self.b
f = Fib()
for i in range(3):
print(next(f))
因此,每次调用next(f)
时,都会生成__next__
返回的生成器对象:
<generator object __next__ at 0x000000000A3E4F68>
<generator object __next__ at 0x000000000A3E4F68>
<generator object __next__ at 0x000000000A3E4F68>
另外,如何为发电机编写unittest?
您仍然需要实现一个send和throw方法 Generator
from collections.abc import Iterator, Generator
import unittest
class Test(unittest.TestCase):
def test_Fib(self):
f = Fib()
self.assertEqual(next(f), 0)
self.assertEqual(next(f), 1)
self.assertEqual(next(f), 1)
self.assertEqual(next(f), 2) #etc...
def test_Fib_is_iterator(self):
f = Fib()
self.assertIsInstance(f, Iterator)
def test_Fib_is_generator(self):
f = Fib()
self.assertIsInstance(f, Generator)
现在:
>>> unittest.main(exit=False)
..F
======================================================================
FAIL: test_Fib_is_generator (__main__.Test)
----------------------------------------------------------------------
Traceback (most recent call last):
File "<stdin>", line 7, in test_Fib_is_generator
AssertionError: <__main__.Fib object at 0x00000000031A6320> is not an instance of <class 'collections.abc.Generator'>
----------------------------------------------------------------------
Ran 3 tests in 0.001s
FAILED (failures=1)
<unittest.main.TestProgram object at 0x0000000002CAC780>
因此,让我们实现一个生成器对象,并利用Generator
collections模块中的抽象基类(请参见其实现的源代码),这意味着我们只需要免费实现send
并throw
-免费给我们close
,__iter__
(返回自身)和__next__
(与.send(None)
)
(请参阅协程的Python数据模型):
class Fib(Generator):
def __init__(self):
self.a, self.b = 0, 1
def send(self, ignored_arg):
return_value = self.a
self.a, self.b = self.b, self.a+self.b
return return_value
def throw(self, type=None, value=None, traceback=None):
raise StopIteration
并使用上述相同的测试:
>>> unittest.main(exit=False)
...
----------------------------------------------------------------------
Ran 3 tests in 0.002s
OK
<unittest.main.TestProgram object at 0x00000000031F7CC0>
美国广播公司Generator
仅在Python
3.要做到这一点没有Generator
,我们需要至少写close
,__iter__
以及__next__
除了我们上面定义的方法。
class Fib(object):
def __init__(self):
self.a, self.b = 0, 1
def send(self, ignored_arg):
return_value = self.a
self.a, self.b = self.b, self.a+self.b
return return_value
def throw(self, type=None, value=None, traceback=None):
raise StopIteration
def __iter__(self):
return self
def next(self):
return self.send(None)
def close(self):
"""Raise GeneratorExit inside generator.
"""
try:
self.throw(GeneratorExit)
except (GeneratorExit, StopIteration):
pass
else:
raise RuntimeError("generator ignored GeneratorExit")
请注意,我close
直接从Python
3标准库复制而未进行任何修改。
本文向大家介绍如何在Eclipse中编写,生成和使用Javadoc?,包括了如何在Eclipse中编写,生成和使用Javadoc?的使用技巧和注意事项,需要的朋友参考一下 要为您的项目生成Java文档,您需要编写有关字段,方法或类的必需信息。 然后按照以下步骤生成文档- 步骤1-打开eclipse,选择选项项目→生成Javadoc。 步骤2-从Java安装目录的bin文件夹中选择javadoc.e
本文向大家介绍如何生成一个随机数?相关面试题,主要包含被问及如何生成一个随机数?时的应答技巧和注意事项,需要的朋友参考一下
我阅读了有关自定义异常和as的内容: Thorben建议:https://stackify.com/java-custom-exceptions/#wpautbox_about Baeldung在这里建议:https://www.baeldung.com/java-new-custom-exception 自定义例外应该比原始例外更有益,否则会失去其目的。正当要做到这一点,我们应该始终将可丢弃的原
我正在尝试编写一个pyspark数据帧到Redshift,但它导致了错误:- java.util.ServiceConfigurationError:org.apache.spark.sql.sources.DataSourceRister:Provider org.apache.spark.sql.avro.avroFileFormat无法实例化 原因:java.lang.nosuchmetho
我已经设置了两个项目,一个“init”和一个库,这是init所需要的。它们都设置了PSR-0自动加载,但是库中的自动加载值不会添加到初始化项目中的供应商/作曲家/autoload_namespaces.php中。 示例作曲家。来自库的json: 示例作曲家。来自需要该库的项目的json: 该库包含文件src/LXP/library/Something中的类LXP\library\Something
问题内容: 我正在寻找一个完全由Java驱动的免费跨平台安装程序生成器(这意味着工作流和插件是用Java编写的)。理想情况下,安装程序应按需下载JRE,而不是将其直接捆绑到安装程序中。这样的东西已经存在了吗? 请注意,InstallAnywhere不再提供免费版本。 问题答案: IzPack 抗原 Launch4J 蚂蚁 Java服务包装器 提起Java安装程序 JSmooth VA安装 pack