假设我有一个带有两个函数的模块myfunctions
:
def functionA():
return'Function A chosen.'
def functionB():
return 'Function B chosen.'
然后,我有一个模块silly
,它对以下函数执行一些操作:
def sillyprinter():
print chosen_function
print chosen_function()
然后,在我的主要剧本中,我有:
import myfunctions
import silly
class FunctionChooser():
def __init__(function_choice="A"):
self.choose_function_given_choice(function_choice)
def do_something_many_times(self):
for i in range(1000):
silly.sillyprinter()
FunctionChooser
的思想是用一些用户给定的信息来初始化它,这些信息与我想从myfunctions
使用哪个函数(A或B)有关。然后,在做出这个选择之后,用户可以调用do_something_many_times
,这将使用另一个模块,该模块将多次使用从myfunctions
中选择的函数。你知道吗
为了提高效率,我想避免以下情况:
1)一次又一次地选择要使用的函数——所以我想做一次选择(在初始化期间),然后以某种方式“保存”它。此要求取消了以下设计的资格:
def sillyprinter(chosen_function):
print chosen_function
print chosen_function()
# =================================
class FunctionChooser():
def __init__(function_choice="A"):
self.function_choice = function_choice
def choose_function_given_choice(self):
if self.function_choice == "A":
return myfunctions.functionA
elif self.function_choice == "B":
return myfunctions.functionB
def do_something_many_times(self):
for i in range(1000):
silly.silly_printer(self.choose_function_given_choice())
2)存储我想选择作为类属性的函数since ^{
def sillyprinter(chosen_function):
print chosen_function
print chosen_function()
# =================================
class FunctionChooser():
def __init__(function_choice="A"):
self.function_choice = function_choice
def choose_function_given_choice(self):
if self.function_choice == "A":
self.chosen_function = myfunctions.functionA
elif self.function_choice == "B":
self.chosen_function = myfunctions.functionB
def do_something_many_times(self):
for i in range(1000):
silly.silly_printer(self.chosen_function)
我目前的想法是:
def sillyprinter(chosen_function):
print chosen_function
print chosen_function()
# =================================
class FunctionChooser():
def __init__(function_choice="A"):
self.function_choice = function_choice
def choose_function_given_choice(self):
if self.function_choice == "A":
self.chosen_function = myfunctions.functionA
elif self.function_choice == "B":
self.chosen_function = myfunctions.functionB
def do_something_many_times(self):
chosen_function = self.chosen_function
for i in range(1000):
silly.silly_printer(chosen_function)
它只是与我在2)中取消的设计稍有不同,因为它只进行一次self
调用,然后将该函数存储为局部变量。你知道吗
Is this the best way to design such "function choice" in Python, given my requirements? (see below)
编辑:我想我应该把要求弄清楚,这样问题就不那么笼统了
self.
访问调用(但通常可能是.
访问调用?)由于numba
使用访问调用优化代码的问题:Design heuristics for writing Python classes that interact with `scipy.integrate.odeint`?
基本答案是,这三个选项中的任何一个都可能是“最佳”的,具体取决于具体情况。但是您所选择的选项之间的差异是微妙的,并且在大多数情况下不太可能显著影响性能。与其在这里担心效率,不如担心概念上的优雅。然后,如果你需要效率,优化。你知道吗
我可以想象,从概念上讲,这三种选择中的任何一种都是可取的。你知道吗
假设函数的选择取决于一个经常变化的值。您必须经常检查它的状态,那么存储它会有什么好处呢?只要每次都查一下就更有意义了。在这种情况下,(1)是最好的选择。
假设函数的选择不会基于一个经常改变的值,或者一个易于“反转控制”的值(即关注变量的代码也知道如何改变函数的选择)。除非您有压倒一切的理由担心单个
.
访问的额外开销,否则只需将其存储为属性。(请注意,在self
中查找属性的成本并不比在其他对象中查找属性的成本高。操作完全相同;self
没有什么特别之处在这种情况下,(2)是最好的选择。假设函数的选择不会基于经常更改的值,而是函数本身会经常被调用。此外,您确信
.
访问正在减慢代码的速度,因为您已经完成了严格的测试。然后将.
访问的结果缓存在局部变量中是有意义的,如选项(3)所示。(但请注意,在选项(3)中,您仍然在使用另一个.
操作,该操作也应该被缓存,就像在Ignacio的回答中一样。)但是要小心过早的优化!每一个局部变量都会给您和您的开发人员带来额外的认知负荷,您必须确保这是值得的。只有如果你真的做过测试的话,才选择这个选项,这会造成显著的速度差异。最后一点注意:在您的示例代码中还有一些额外的复杂性,我假设这些复杂性应该是为了唤起复杂性,而不是在这种特殊情况下的特定目的。例如,给定您实际发布的代码,
choose_function_given_choice
函数是非常无用的。但我想你已经知道了。不过,要重申显而易见的一点,你应该以最简单的方式实现这一切。你知道吗不,Python中的函数是一级对象;将它们视为一级对象。你知道吗
相关问题 更多 >
编程相关推荐