我有一个带有while循环的函数。在我启动这个函数之前,我希望能够决定是每次循环时都导出一个图像,还是只显示它,两者都做还是都不做。
我不想在循环中输入一个“if”,每次我经历它时都会被问到,所以我想,我只是编写该函数的4个不同版本(循环,loop_show,loop_export,loop_show_export)。但我认为一定有一种方法可以不复制粘贴函数的其余部分。
有办法做到这一点吗?或者有没有一个更好的方法来装饰或其他东西?
def main():
...
while True:
...
####### code that I need to dis-/enable #######
for image in images:
video_in.write(image) # preparation for export
Show.show_win('in', image) # show input
###############################################
...
在你的情况下,瓦伦蒂诺建议使用“如果”陈述更有意义。
但是,在某些情况下,您不能或者不想对每个可能的选项进行硬编码(例如,选项太多,或者用户应该能够定义自定义选项)。这类似于策略模式
然后可以显式地为类提供必要的方法。
def main(postprocessing=None):
...
while True:
...
if postprocessing:
for image in images:
postprocessing(image)
例如,您可以使用< code>main(后处理=video_in.write)调用它
如果需要,还可以在后处理参数中支持步骤列表,以保持超级灵活。我在这里没有这样做,以保持代码更简单。
此策略的缺点是每个后处理步骤都应使用相同的 API。因此,您的显示方法不会开箱即用。您必须使用类似以下功能的内容:
main(后处理=部分(Show.Show_win,'in'))
这当然增加了额外的复杂性。所以对于你的情况,重复if语句会更清楚。
太酷了。我很明白你的意思。我最近刚刚经历过。如果在检查完成并切换到另一个分支后将毫无用处,它将继续运行。
举个例子来解释这个问题。我们有一个方法或回调,只需要在第一次运行一些东西。或者在一些迭代次数之后。一旦切换,它将只在else或第二个代码上运行。
因此,拥有一个无用的if是一个无用开销。如果我们能完全改变方法,那就太好了。
这是如何用JavaScript实现的
const execCallback = version1WithCheck;
function version1WithCheck() {
if (myCondition) {
// do something
} else {
execCallback = version2NoCheck; //<----- changing the ref of your execCallback variable (which need to be global (in js it will be a closure))
execCallback();
}
}
function version2NoCheck() {
}
function someEventListener() {
execCallback();
};
event.listen(someEventListener);
这里有一个真实的例子:
private _tradesInsertToDbWithCheck(trades: Trade[]) {
if (!this._checkIfTradesNeedToBeInserted(trades)) {
const sortedTradesToBeInserted = trades.filter((trade: Trade) => {
const firstTradeInfo = this._firstTradeMapping[
objectToExchangeSymbolSignature<Trade>(trade)
];
return trade.id >= firstTradeInfo.id;
});
this._insertTradesIntoDb(sortedTradesToBeInserted);
} else {
//-------- here i switch -----
// ||
// \/
this._insertToDbOnProcessCallback = this._tradesInsertToDbWithoutCheck;
this._insertToDbOnProcessCallback(trades);
}
}
和另一个例子:
这一个只有第一个调用将需要检查。它不会用于所有其余的一个。
exchangeClient.onTradeFeedCallback = this._onFirstFeedTrade as OnTradeFeedCallback;
//---------------------^^ we set our ref callback (to first time only version)
exchangeClient.streams[symbol as string_symbol] =
exchangeClient.client.ws.trades(
symbol,
(trade) => { //<------------ here the callback
(exchangeClient.onTradeFeedCallback as OnTradeFeedCallback)(trade as Trade, workers, exchangeClient);
//----------------------------^^^^ here calling our refCallback
}
);
第一次版本法
private _onFirstFeedTrade(trade: Trade, workers: Worker[], exchangeClient: ExchangeClientObject) {
/**
* this run only once
*/
//_______________alter callback function (this no more will be called)
exchangeClient.onTradeFeedCallback = this._onTradeFeed;
// do some things
// next time this._onTradeFeed will be called
我想现在这个想法已经很清楚了。
callback = None
def version1(index):
global callback
print('im version 1')
if index == 5:
callback = version2 // <---- switch upon that condition
def version2(index):
global callback
print('im vesrion 2')
callback = version1
for i in range(0,20):
callback(i)
最后,我们需要引入分支预测器及其工作原理。以及为什么分支可能不好。以及为什么预测器可以做大事。最近的cpu做得很好。
为了不走多远,这里的链接关于这个主题
https://stackoverflow.com/a/11227902/5581565
编译器如何处理编译时分支?
https://stackoverflow.com/a/32581909/7668448
为了不使这个列表变得更长,我就说到这里。以及在被多次调用回调或循环中使用if else。如果过了一段时间后,它只在一个分支上继续执行。我认为使用运行统计的分支预测器将为保持运行的分支进行优化。那么这样可能就一点都不重要了。我会进一步调查此事,做一些基准测试,然后我会更新答案。但这一点是需要注意或考虑的。
我希望这有所帮助。快乐编码。
如果我理解正确,这就是你需要的:
def main(show=False, export=False):
...
while True:
...
####### code that I need to dis-/enable #######
for image in images:
if export:
video_in.write(image) # preparation for export
if show:
Show.show_win('in', image) # show input
###############################################
...
将函数调用为< code>main()时,< code>show和< code>export参数默认为< code>False,因此循环中的两个< code>if不执行。< br >如果调用< code>main(show=True),则执行< code>if show:。< br >如果调用< code>main(export=True),则执行< code>if export:。< br >如果调用< code>main(show=True,export=True),则两个< code>if都执行。
正如人们在评论中所说,检查布尔值几乎不需要时间,代码是可读的,在几乎相同的函数中没有重复的行。无需寻找更详细的解决方案。
函数功能:获得 LuaBox 当前版本 函数方法 version = device.getLuaBoxVer() 返回值 类型 说明 version string 返回获得 LuaBox 当前版本如:1.0 函数用例 version = device.getLuaBoxVer() dialog(version,5000) 注意事项 目前积木编程函数和触动精灵函数不通用,请仔细查看本手册,此手册中
函数功能:获取系统版本号 函数方法 sysver = device.getOSVer() 返回值 类型 说明 sysver string 返回系统版本号如:7.0 函数用例 sysver = device.getOSVer(); --获取系统版本 dialog(sysver,5000) 注意事项 目前积木编程函数和触动精灵函数不通用,请仔细查看本手册,此手册中函数仅支持积木编程,不支持触动
问题内容: 假设我有如下定义的Python函数: 我可以使用获取函数的名称。如上所述,我如何以编程方式获取其源代码? 问题答案: 如果该功能来自文件系统上可用的源文件,则可能会有帮助: 如果foo定义为: 然后: 返回值: 但是我相信,如果函数是从字符串,流中编译的,或者是从编译文件中导入的,那么您将无法检索其源代码。
我需要瞄准地图函数中的所有组件,但我只得到其中的最后一个组件。
问题内容: 我想从函数本身内部打印python函数的文档字符串。例如 目前,在定义之后,我将直接执行此操作。 但宁愿让函数自己执行此操作。 我已经尝试在my_function内调用它 ,但这没有用。 问题答案: 只要您不更改绑定到名称的对象,此方法就可以工作。 您会执行此操作的情况很少见,但确实会发生。 但是,如果您编写这样的装饰器: 现在您可以执行以下操作: 这将确保您的函数获得对自身的引用(类
问题内容: 我想对Python中的函数进行深拷贝。该 副本 模块是没有帮助的,根据文件,其中说: 该模块不复制诸如模块,方法,堆栈跟踪,堆栈框架,文件,套接字,窗口,数组或任何类似类型的类型。它通过不变地返回原始对象来“复制”函数和类(浅层和深层)。这与泡菜模块处理这些食物的方式兼容。 我的目标是使两个函数具有相同的实现,但具有不同的文档字符串。 那怎么办呢? 问题答案: FunctionType