- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我遇到了一个交给我的有效的 python 脚本。我理解该脚本的目的及其在与其他模块交互的大局中的作用,以及它在大多数地方的内部架构。但是,我必须对该脚本进行大修,主要是删除一些旧类并添加大量新子类,以便它提供我们需要的更多功能。我的问题主要来自于我所看到的某些函数返回包含该对象的列表与 yield
之间存在一些无法解释的差异。将该对象返回到自身。
# These functions are methods that belong to a class.
# There is a top level script that instantiates that class and calls
# these methods on that class, and depending on the `self.mode` variable located in the instance namespace, it invokes the different subsequent methods,
# which are either generateHybridSim() or generatePureHwSim()
# It is worth pointing out here that HybridSimStep and ShangHWSimStep
# are both classes themselves and that they will be instantiated later on as
# I will describe after this chunk of code
def generateSubTests(self) :
if self.mode == TestStep.HybridSim :
return self.generateHybridSim()
elif self.mode == TestStep.PureHWSim or self.mode == TestStep.AlteraSyn \
or self.mode == TestStep.AlteraNls or self.mode == TestStep.XilinxSyn :
return self.generatePureHWSim()
return []
def generateHybridSim(self) :
return [ HybridSimStep(self) ]
def generatePureHWSim(self) :
yield ShangHWSimStep(self)
num_iter = self.max_scheduling_iterations
if num_iter > 1 :
for i in range(1) :
sim_step = ShangHWSimStep(self)
sim_step.option = self.option.copy()
sim_step.hls_base_dir = os.path.join(sim_step.hls_base_dir, str(i))
sim_step.rtl_output = os.path.join(sim_step.hls_base_dir, sim_step.test_name + ".sv")
sim_step.option['max_scheduling_iterations'] = i + 1
yield sim_step
最终,无论 generateHybridSim()
是否或 generatePureHwSim()
方法被调用时,它们都以完全相同的方式在另一个模块中被调用:
# The 'job' that is in front of generateSubTests() is the instance's
# variable name, and you can see that prepareTest() and runTest()
# methods get called on the subtest iterable object, which so happens
# to be class's instance.
# So in short, these two methods are not defined within generateSubTests() method, but
# rather under the classes that the generateHybridSim() and
# generatePureHWSim() methods had returned or yielded respectively.
for subtest in job.generateSubTests() :
subtest.prepareTest()
subtest.runTest()
time.sleep(1)
next_active_jobs.append(subtest)
我现在真的很迷茫,不知道使用yield
有什么意义?这里与 return
,我需要弄清楚为什么以前写这个脚本的程序员会那样做。这是因为我将实现新的子类,这些子类本身必须包含自己的 generateSubTests()
方法并且必须遵循相同的函数调用。他所做的事实for subtest in job.generateSubTests
意味着我只能返回一个包含类的列表,或者生成类本身,否则它不适合 python for 循环迭代协议(protocol)。我尝试通过修改 yield
来测试代码generatePureHWSim()
中的陈述至 return
像 generateHybridSim()
中的那些它似乎运行良好,尽管我不确定是否引入了任何细微的错误。但是,我不知道我是否在这里遗漏了什么。以前的程序员是不是想促进并发http://www.dabeaz.com/coroutines/index.html通过使用 yield
将函数转换为生成器?
他已经完全离开了我们的实验室,所以我无法向他寻求帮助。
另外,我已经阅读了 yield
来自各种来源,包括帖子: What does the "yield" keyword do in Python? ;尽管他们帮助我理解了 yield 的作用,但我仍然不明白在这里使用它对我们的上下文有何帮助。事实上,我什至不明白为什么以前的程序员要用for subtest in job.generateSubTests() :
来实现一个循环。并强制 generatePureHWSim()
和 generateHybridSim()
方法本身必须是生成器,这样我们就可以有一个循环来调用 prepareTest()
的其他方法。和 runTest()
在实例上。为什么他不能直接返回类并调用那些方法???
这真让我失望。我将非常感谢这里的任何帮助!!!谢谢。
PS:还有一个问题 - 我注意到,一般来说,如果您有一个函数定义为:
def a():
return b
print "Now we return c"
return c
似乎每当执行其中的第一条语句时,b
被返回,然后函数完成执行并且c
永远不会返回,因为 return b
之后的声明永远不会被触及。尝试添加打印语句,您会发现它永远不会被打印出来。
然而,当谈到yield
时:
def x():
yield y
print "Now we yield z"
yield z
我注意到即使在第一个 yield y
之后语句已经执行,后续yield z
将被执行。尝试添加 print 语句,您会看到它被打印出来了。这是我在调试上述代码时观察到的,我不理解 yield
之间的这种行为差异。和 return
.有人可以启发我吗?
谢谢。
最佳答案
我很高兴地告诉您,这不涉及并发。
之前的程序员希望generateSubTests
返回一组子测试(可能是 0、1 或更多子测试)。然后将在 for subtest in job.generateSubTests():
循环中相应地处理每个子测试。
实际上,如果您仔细观察,generateHybridSim
会返回一个包含一个子测试的普通 Python 列表,而不是生成器对象。但列表和生成器对象在这种情况下实际上是非常相似的东西 - 一系列子测试。
您必须意识到 generatePureHWSim(self)
几乎等同于以下代码:
def generatePureHWSim(self) :
output_list = []
output_list.append(ShangHWSimStep(self))
num_iter = self.max_scheduling_iterations
if num_iter > 1 :
for i in range(1) :
sim_step = ShangHWSimStep(self)
sim_step.option = self.option.copy()
sim_step.hls_base_dir = os.path.join(sim_step.hls_base_dir, str(i))
sim_step.rtl_output = os.path.join(sim_step.hls_base_dir, sim_step.test_name + ".sv")
sim_step.option['max_scheduling_iterations'] = i + 1
output_list.append(sim_step)
return output_list
但有一个异常(exception)。虽然上面的代码预先进行了所有计算并将所有结果放入内存中的列表中,但带有 yield
的版本将立即产生单个子测试,并且仅在要求下一个结果时才进行以下计算.
这有很多潜在的好处,包括:
关于您的第二个问题,正如您观察到的那样,当您点击 return 语句时,Python 函数中的执行结束。在同一代码块中的 return
语句之后放置更多代码是没有意义的。
yield
做的事情稍微复杂一些,因为它返回一个更接近列表的生成器对象。
下面的代码:
def generator_example():
yield 1
print "x"
yield 2
真的不能与:
def return_example():
return 1
print "x"
return 2
但更接近于:
def list_example():
output_list = []
output_list.append(1)
print "x"
output_list.append(2)
return output_list
generator_example
和 list_example
都返回一个可以使用 for 循环迭代的序列。
对代码的无关注释
虽然下面的部分很奇怪。
if num_iter > 1 :
for i in range(1) :
sim_step = ShangHWSimStep(self)
没有理由使用 for i in range(1)
,它只循环一次,i
设置为 0
。我将删除 for i in range(1)
位,缩进代码并将所有出现的 i 替换为 0,或者更好的是,重命名 i 以提供更多信息并将其明确设置为 0 .
关于python - 关于我在其他地方找不到答案的 Python 'yield' 关键字的问题,以及它在我正在处理的代码中的具体用途,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28846032/
我正在处理一组标记为 160 个组的 173k 点。我想通过合并最接近的(到 9 或 10 个组)来减少组/集群的数量。我搜索过 sklearn 或类似的库,但没有成功。 我猜它只是通过 knn 聚类
我有一个扁平数字列表,这些数字逻辑上以 3 为一组,其中每个三元组是 (number, __ignored, flag[0 or 1]),例如: [7,56,1, 8,0,0, 2,0,0, 6,1,
我正在使用 pipenv 来管理我的包。我想编写一个 python 脚本来调用另一个使用不同虚拟环境(VE)的 python 脚本。 如何运行使用 VE1 的 python 脚本 1 并调用另一个 p
假设我有一个文件 script.py 位于 path = "foo/bar/script.py"。我正在寻找一种在 Python 中通过函数 execute_script() 从我的主要 Python
这听起来像是谜语或笑话,但实际上我还没有找到这个问题的答案。 问题到底是什么? 我想运行 2 个脚本。在第一个脚本中,我调用另一个脚本,但我希望它们继续并行,而不是在两个单独的线程中。主要是我不希望第
我有一个带有 python 2.5.5 的软件。我想发送一个命令,该命令将在 python 2.7.5 中启动一个脚本,然后继续执行该脚本。 我试过用 #!python2.7.5 和http://re
我在 python 命令行(使用 python 2.7)中,并尝试运行 Python 脚本。我的操作系统是 Windows 7。我已将我的目录设置为包含我所有脚本的文件夹,使用: os.chdir("
剧透:部分解决(见最后)。 以下是使用 Python 嵌入的代码示例: #include int main(int argc, char** argv) { Py_SetPythonHome
假设我有以下列表,对应于及时的股票价格: prices = [1, 3, 7, 10, 9, 8, 5, 3, 6, 8, 12, 9, 6, 10, 13, 8, 4, 11] 我想确定以下总体上最
所以我试图在选择某个单选按钮时更改此框架的背景。 我的框架位于一个类中,并且单选按钮的功能位于该类之外。 (这样我就可以在所有其他框架上调用它们。) 问题是每当我选择单选按钮时都会出现以下错误: co
我正在尝试将字符串与 python 中的正则表达式进行比较,如下所示, #!/usr/bin/env python3 import re str1 = "Expecting property name
考虑以下原型(prototype) Boost.Python 模块,该模块从单独的 C++ 头文件中引入类“D”。 /* file: a/b.cpp */ BOOST_PYTHON_MODULE(c)
如何编写一个程序来“识别函数调用的行号?” python 检查模块提供了定位行号的选项,但是, def di(): return inspect.currentframe().f_back.f_l
我已经使用 macports 安装了 Python 2.7,并且由于我的 $PATH 变量,这就是我输入 $ python 时得到的变量。然而,virtualenv 默认使用 Python 2.6,除
我只想问如何加快 python 上的 re.search 速度。 我有一个很长的字符串行,长度为 176861(即带有一些符号的字母数字字符),我使用此函数测试了该行以进行研究: def getExe
list1= [u'%app%%General%%Council%', u'%people%', u'%people%%Regional%%Council%%Mandate%', u'%ppp%%Ge
这个问题在这里已经有了答案: Is it Pythonic to use list comprehensions for just side effects? (7 个答案) 关闭 4 个月前。 告
我想用 Python 将两个列表组合成一个列表,方法如下: a = [1,1,1,2,2,2,3,3,3,3] b= ["Sun", "is", "bright", "June","and" ,"Ju
我正在运行带有最新 Boost 发行版 (1.55.0) 的 Mac OS X 10.8.4 (Darwin 12.4.0)。我正在按照说明 here构建包含在我的发行版中的教程 Boost-Pyth
学习 Python,我正在尝试制作一个没有任何第 3 方库的网络抓取工具,这样过程对我来说并没有简化,而且我知道我在做什么。我浏览了一些在线资源,但所有这些都让我对某些事情感到困惑。 html 看起来
我是一名优秀的程序员,十分优秀!