假设您要使用Task2Do类的对象表示要执行的任务。 这些对象是可运行的,也就是说,它们有一个执行任务doTask 。
另一方面,你有这些对象的队列(在python中的例子):
a = Task2Do(method1, args1) b = Task2Do(method1, args2) c = Task2Do(method2, args3) pending = [a,b,c]您想要运行所有pending任务:
for t in pending: t.doTask()有人会引入错误,因此同一对象在pending队列中出现两次:
pending = [a,a,c]您可以保护您的代码:
class Task2Do: def __init__(self, target, args): self._todo = target self._args = args self._done = False def doTask(self): if not self._done: # Protection against double execution self._todo(*self._args) self._done = True我的问题是:这是否有一个名称作为设计模式? 我听说有些人已经实现了类似的东西,在C ++中调用了对象析构函数。
你知道其他类似的模式吗?
Suppose you are representing some task to do using objects of a class Task2Do. These objects are runnable, that is, they have a method which perform a task doTask.
On the other hand, you have a queue of these objects (example in python):
a = Task2Do(method1, args1) b = Task2Do(method1, args2) c = Task2Do(method2, args3) pending = [a,b,c]You want to run all pending tasks:
for t in pending: t.doTask()It can happen that someone introduces a bug so the same object appears twice in the pending queue:
pending = [a,a,c]You can protect your code:
class Task2Do: def __init__(self, target, args): self._todo = target self._args = args self._done = False def doTask(self): if not self._done: # Protection against double execution self._todo(*self._args) self._done = TrueMy question is: Does this have a name as a design pattern? I heard some people have implemented something similar calling the object destructor in C++.
What other similar patterns do you know?
最满意答案
我能想到的最简单的方法是:
class Task2Do: def __init__(self, target, args): self._todo = target self._args = args def doTask(self): self._todo(*self._args) self._todo = lambda: None self._args = ()这似乎比旗帜更清洁。 或者,使self._todo在第二次调用时抛出错误。 你甚至可以通过将self._todo设置为None 。
说实话,任务并不一定需要是课程。 大多数情况下,只有拥有一个功能才更容易和更惯用。 在这种情况下,您可以使用生成器来获得一次性使用:
def task2do(target, *args, **kwargs): def iter_run_once(): yield target(*args, **kwargs) raise ValueError("Multiple calls to one-time-use task") return iter_run_once().__next__ F = task2do(print, 1, 2, 3) F() #>>> 1 2 3 F() #>>> Traceback (most recent call last): #>>> File "", line 14, in <module> #>>> File "", line 4, in iter_run_once #>>> ValueError: Multiple calls to one-time-use task为了好玩,请注意您还可以:
def task2do(target, *args, **kwargs): return (lambda: (yield target(*args, **kwargs)))().__next__;)
The simplest method I can think of is:
class Task2Do: def __init__(self, target, args): self._todo = target self._args = args def doTask(self): self._todo(*self._args) self._todo = lambda: None self._args = ()which seems cleaner than a flag. Alternatively, make self._todo throw an error on second call. You could even do that by just setting self._todo to None.
To be honest, though, tasks don't really need to be classes. Most of the time it's easier and more idiomatic just to have a function. In that case, you could use a generator to get one-time-use:
def task2do(target, *args, **kwargs): def iter_run_once(): yield target(*args, **kwargs) raise ValueError("Multiple calls to one-time-use task") return iter_run_once().__next__ F = task2do(print, 1, 2, 3) F() #>>> 1 2 3 F() #>>> Traceback (most recent call last): #>>> File "", line 14, in <module> #>>> File "", line 4, in iter_run_once #>>> ValueError: Multiple calls to one-time-use taskFor fun, note you can also do:
def task2do(target, *args, **kwargs): return (lambda: (yield target(*args, **kwargs)))().__next__;)
更多推荐
发布评论