基于输入参数的Python导入

2024-04-25 09:11:34 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个看似简单的Python代码设计问题,但我没有找到任何优雅的解决方案。我有一组模块(下面的示例中有两个)定义了同名函数,这些函数计算相同的东西,但使用不同的算法:

算法_a.py:

def compute_1(x):
   # do some computation
   return (x+1.)**2

def compute_2(x):
   # do some other computation

# etc

算法_b.py:

^{pr2}$

这两个模块都有大约10个功能,但未来可能会增加。在

在第三个模块中,我定义了一些不知道如何执行计算的函数,也就是说,它们只关心得到正确的答案。用户的接口由类提供。总之,第三个模块看起来类似于:

在模拟.py公司名称:

import XXX as algo #????

def do_computation_1(x):

   v1 = algo.compute_1(x)
   v2 = algo.compute_2(x)

   # Do some computations using v1, v2 
   return result

def do_computation_2(x):
   return algo.compute_2(x)

# etc etc

class Simulation(object):

  def __init__(self, method):
     # Do some magic here so that
     # if method == "A":
     #   algo = algorithm_a
     # if method == "B"
     #   algo = algorithm_b

  def run(self, x):
     do_computation_1(x)
     do_computation_2(x)

如何在do\u calculation()中加载并应用正确的模块,以依赖于提供给类的方法参数?在

请注意,dou计算函数需要保持在Simulation类之外。在

结论:下面@BrenBarn的评论很好地总结了可用的选择。谢谢大家的大力帮助!在


Tags: 模块函数py算法return定义defetc
2条回答

根据代码的结构方式,不能让导入依赖于传递给类的参数。Python文件是自上而下执行的。导入发生在类定义之前,因此在定义类时,导入已经发生。(在实例化类之前,您不会传入method,这将在以后进行)

如果可以导入这两个模块,而您只想使用指定的模块,那么您几乎可以按照您在注释中所写的内容来执行:

import algorithm_a
import algorithm_b

class Simulation(object):

    def __init__(self, method):
        if method == "A":
            self.algo = algorithm_a
        if method == "B"
            self.algo = algorithm_b

    def do_computation(self, x):
        return self.algo.compute(x)

    def run(self, x):
        self.do_computation(x)

(我在这里将do_computation作为类的一个方法。如果它的行为由传递给类的参数决定,那么将它作为一个单独的函数没有多大意义。)

如果模块的实际导入可能很慢,您可以有条件地导入一个模块或其他模块,如Reblochon的回答所示。但是,要做到这一点,必须将导入放在类中。如果要通过Simulation("A")之类的方法指定算法,则无法确定在执行import simulation时要执行哪个导入,因为此时尚未指定算法;必须等到实际调用Simulation("A")。(如果进口缓慢,这将导致在该点减速,这可能是不可取的。)

编辑:如果因为Numba而需要使do_computation成为一个全局函数,可以通过设置一个全局变量来解决它。将__init__更改为:

^{pr2}$

并创建一个全局do_computation函数,如下所示:

^{3}$

这将更加令人困惑,因为每次您创建一个新的Simulation时,它都会更改全局行为,即使是对于以前创建的模拟也是如此。但是如果你不是同时用不同的算法创建多个模拟,那就没问题了。在

更好的方法是实际保存(或传递)要使用的函数。。E、 g

import algorithm_a
import algorithm_b


class Simulation(object):

  def __init__(self, method):
     # Do some magic here so that
     if method == "A":
       self.compute_func = algorithm_a.compute
     if method == "B"
       self.compute_func = algorithm_b.compute

  def run(self, x):
     self.compute_func(x)

如果您确实必须使用外部def do_computation(x)函数,则可以传递要用作参数的算法

^{pr2}$

相关问题 更多 >