在switch字典中执行函数

时间:2017-01-17 13:18:08

标签: python function dictionary

将我开发的所有模块放入主程序时遇到了问题。我创建的切换词典如下所示:

def Tank_Shape_Calcs(Tank_Shape, level, area, dish, radius, length, Strapping_Table, Tank_Number):

    switcher = {
        0: vertical.Vertical_Tank(level, area),
        1: horiz.Horiz_Cylinder_Dished_Ends(dish, radius, level, length),
        2: strapping.Calc_Strapped_Volume(Strapping_Table, level),
        3: poly.Fifth_Poly_Calcs(Tank_Number)
    }
    return switcher.get(Tank_Shape, "ERROR: Tank type not valid")

坦克形状在主文件中设置为每个坦克的循环。第一个坦克有Tank_Shape = 2所以我希望它能执行Calc_Strapped_Volume()函数。

我已经尝试过测试,切换器功能肯定是Tank_Shape 2。此外,如果我将函数更改为字符串,它将打印出正确的字符串。

问题是函数似乎是按顺序执行的,直到调用了正确的函数。这会导致错误,因为我使用的数据只能使用正确的函数。

有没有办法只执行正确的功能?

3 个答案:

答案 0 :(得分:39)

您在构建字典时执行所有功能,而不是在访问密钥时执行。

您需要使用lambda(没有任何参数,它们已知),以确保仅在需要时调用该函数:

switcher = {
    0: lambda : vertical.Vertical_Tank(level, area),
    1: lambda : horiz.Horiz_Cylinder_Dished_Ends(dish, radius, level, length),
    2: lambda : strapping.Calc_Strapped_Volume(Strapping_Table, level),
    3: lambda : poly.Fifth_Poly_Calcs(Tank_Number)
}

然后在您返回时调用,并将错误消息作为返回它的lambda:

return switcher.get(Tank_Shape, lambda : "ERROR: Tank type not valid")()

答案 1 :(得分:17)

如上所述,在字典构造期间将调用这些函数。除此之外,还有我在这里看到的另外两个问题:

  • 在每次调用函数switcher期间重新定义Tank_Shape_Calcs时,这通常不是一个好主意。
  • 要求传递所有参数(由于它们被定义为位置),当只需要少数几个时,这就是为什么我们有*args :-)

如果我对您所做的事情的理解是正确的,我会将切换器移到该函数之外,作为Tank_Shapefunction对象映射:

switcher = {
    0: vertical.Vertical_Tank,
    1: horiz.Horiz_Cylinder_Dished_Ends,
    2: strapping.Calc_Strapped_Volume,
    3: poly.Fifth_Poly_Calcs
}

然后,定义Tank_Shape_Calcs以将多余的参数作为带有*args的元组:

def Tank_Shape_Calcs(Tank_Shape, *args):
    return switcher.get(Tank_Shape, lambda *_: "ERROR: Tank type not valid")(*args)

并在.get之后调用你的函数。

这也是让Jean在lambda中定义.get的诀窍,但是*_也是如此,以便允许它被许多args调用(这是因此忽略了。)

答案 2 :(得分:7)

您在代码中所做的是使用整数键(0-3)创建字典,并将函数结果创建为值。因此,您首先调用所有函数,然后访问这些函数的返回值。我会将您的代码更改为:

def Tank_Shape_Calcs(Tank_Shape, level, area, dish, radius, length, Strapping_Table, Tank_Number):
    switcher = {
        0: (vertical.Vertical_Tank, (level, area)),
        1: (horiz.Horiz_Cylinder_Dished_Ends, (dish, radius, level, length)),
        2: (strapping.Calc_Strapped_Volume, (Strapping_Table, level)),
        3: (poly.Fifth_Poly_Calcs, (Tank_Number,))
    }
    func, args = switcher.get(Tank_Shape, (None, None))
    if func is not None: 
        return func(*args)

在这里,您首先获得要使用相应参数调用的函数并调用它。