在 Python 中的不同 switch-case 替换之间进行选择 - 字典还是 if-elif-else? [英] Choosing between different switch-case replacements in Python - dictionary or if-elif-else?

查看:25
本文介绍了在 Python 中的不同 switch-case 替换之间进行选择 - 字典还是 if-elif-else?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近阅读了建议不要在支持 switch-case 的语言中使用 switch-case 语句的问题.就 Python 而言,我已经看到了许多 switch case 替换,例如:

I recently read the questions that recommend against using switch-case statements in languages that do support it. As far as Python goes, I've seen a number of switch case replacements, such as:

  1. 使用字典(许多变体)
  2. 使用元组
  3. 使用函数装饰器(http://code.activestate.com/recipes/440499/)
  4. 使用多态(推荐方法而不是类型检查对象)
  5. 使用 if-elif-else 阶梯
  6. 甚至有人推荐了访问者模式(可能是外在的)

鉴于有多种选择,我在决定对特定代码段做什么时有点困难.我想了解选择这些方法之一而不是其他方法的标准.此外,对于在我无法决定的特定情况下该怎么做的建议(附有选择的解释),我将不胜感激.

Given the wide variety of options, I am having a bit of difficulty deciding what to do for a particular piece of code. I would like to learn the criteria for selecting one of these methods over the other in general. In addition, I would appreciate advice on what to do in the specific cases where I am having trouble deciding (with an explanation of the choice).

具体问题如下:
(1)

Here is the specific problem:
(1)

def _setCurrentCurve(self, curve):
        if curve == "sine":
            self.currentCurve =  SineCurve(startAngle = 0, endAngle = 14,
            lineColor = (0.0, 0.0, 0.0), expansionFactor = 1,
            centerPos = (0.0, 0.0))
        elif curve == "quadratic":
            self.currentCurve = QuadraticCurve(lineColor = (0.0, 0.0, 0.0))

此方法由 qt-slot 调用,以响应从菜单中选择绘制曲线.一旦应用程序完成,上述方法将包含总共4-7条曲线.在这种情况下使用一次性字典是否合理?由于最明显的方法是 if-elif-else,我应该坚持吗?我也考虑在这里使用 **kargs(在朋友的帮助下),因为所有曲线类都使用 **kargs...

This method is called by a qt-slot in response to choosing to draw a curve from a menu. The above method will contain a total of 4-7 curves once the application is complete. Is it justified to use a throw away dictionary in this case? Since the most obvious way to do this is if-elif-else, should I stick with that? I have also consider using **kargs here (with a friends help) since all the curve classes use **kargs...

(2)
第二段代码是一个 qt-slot,当用户更改曲线的属性时会调用它.基本上,插槽从 gui (spinBox) 获取数据并将其放入适当曲线类的实例变量中.在这种情况下,我又遇到了同样的问题——我应该使用字典吗?

(2)
This second piece of code is a qt-slot that is called when the user changes a property of a curve. Basically the slot takes the data from the gui (spinBox) and puts it in an instance variable of the appropriate curve class. In this case, I again have the same question - should I use a dict?

这是前面提到的插槽-

def propertyChanged(self, name, value):
    """A Qt slot, to react to changes of SineCurve's properties."""
    if name == "amplitude":
        self.amplitude = value
    elif name == "expansionFactor":
        self.expansionFactor = value
    elif name == "startAngle":
        self.startAngle = value
    elif name == "endAngle":
        self.endAngle = value  

供参考,这里是连接到上述插槽的代码 -

For reference, here is the code for connecting to the above slot -

def _connectToPage(self, page):
    for connectionData in page.getConnectibles():
        self.connect(connectionData["object"],
                    SIGNAL(connectionData["signal"]),
                    lambda value, name = connectionData["property"]:\
                        self.currentCurve.propertyChanged(name, value))
        self.connect(connectionData["object"],
                    SIGNAL(connectionData["signal"]),
                    self.hackedDisplayArea.update) 

注意 - self.endAngle 等在构造函数中初始化.

Note - The self.endAngle etc. are initialized in the constructor.

据我所知,选择 dict 的原因是为了快速查找.什么时候有保证?当我有 100 个或更多案例时?每次调用函数时都继续构建和丢弃字典是个好主意吗?如果我在函数之外为此目的构建了一个 dict,我是否应该检查它是否需要在其他地方?如果其他地方不需要它会怎样?

As far as I know, the reasons for choosing a dict is for fast lookup. When is that warranted? when I have 100 cases or more? Is it a good idea to keep building and throwing away a dictionary each time the function is called? If I build a dict for this purpose outside a function, should I check If it is needed elswhere? What happens if it is not needed elsewhere?

我的问题是,如果有的话,最佳实践是什么?处理事情的最佳/最优雅的方式是什么?换句话说,何时使用 if-elif-else,何时使用其他选项?

My question is what is the best-practice if there is one? What is the best/most elegant way to go about things? Put in yet another way, when to use if-elif-else, when to use each of the other options?

推荐答案

叹气.对问题的错误部分太纠结了.switch 语句不是问题.表达另类"的方式有很多种,但不会增加含义.

Sigh. Too much hand-wringing over the wrong part of the problem. The switch statement is not the issue. There are many ways of expressing "alternative" that don't add meaning.

问题是意义 -- 不是技术声明的选择.

The issue is meaning -- not technical statement choices.

共有三种常见模式.

  • 将键映射到对象.如果字典几乎是完全静态的,并且您有一个简单的键和另一个更复杂的东西之间的映射,请使用它.每次需要时动态构建字典是愚蠢的.如果这是您意思,您可以使用它:您的条件"是映射到对象的简单静态键值.

  • Mapping a key to an object. Use a dictionary if it is almost totally static and you have a mapping between a simple key and another more complex thing. Building a dictionary on the fly each time you need it is silly. You can use this if it's what you mean: your "conditions" are simple, static key values that map to objects.

子类之间的不同行为.使用多态而不是类型检查对象.正确的.如果您在多个类中具有相似的对象并具有不同的行为,则它们应该是多态的.尽可能经常使用它.

Variant behavior among subclasses. Use Polymorphism instead of type checking objects. Correct. If you have similar objects in multiple classes with variant behavior, they should be polymorphic. Use this as often as possible.

其他变体行为.使用 if-elif-else 阶梯.当您没有大量静态键值映射时使用此选项.当条件复杂时使用此选项,或者您指的是过程,而不是对象.

Other variant behavior. Use an if-elif-else ladder. Use this when you don't have largely static key-to-value mapping. Use this when the conditions are complex, or you mean procedures, not objects.

其他一切都只是可以实现类似结果的棘手代码.

Everything else is just tricky code that can achieve similar results.

使用元组.这只是没有映射的字典.这需要搜索,并且应尽可能避免搜索.不要这样做,效率低下.使用字典.

Using a Tuple. This is just dictionary without the mapping. This requires search, and search should be avoided whenever possible. Don't do this, it's inefficient. Use a dictionary.

使用函数装饰器(http://code.activestate.com/recipes/440499/).恶心.这隐藏了您正在解决的问题的 if-elif-elif 性质.不要这样做,这些选择并不明显排他性.使用其他任何东西.

Using a function decorator (http://code.activestate.com/recipes/440499/). Icky. This conceals the if-elif-elif nature of the problem you're solving. Don't do this, it isn't obvious that the choices are exclusive. Use anything else.

有人甚至推荐了访客模式.当您有一个遵循 复合 设计模式的对象时,请使用它.这取决于多态性的工作,所以它并不是一个真正不同的解决方案.

Someone even recommended the Visitor pattern. Use this when you have an object which follows the Composite design pattern. This depends on polymorphism to work, so it's not really a different solution.

这篇关于在 Python 中的不同 switch-case 替换之间进行选择 - 字典还是 if-elif-else?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆