当前位置:  开发笔记 > 编程语言 > 正文

在Python中选择不同的switch-cases替换 - 字典或if-elif-else?

如何解决《在Python中选择不同的switch-cases替换-字典或if-elif-else?》经验,为你挑选了2个好方法。

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

    使用字典(许多变体)

    使用元组

    使用函数装饰器(http://code.activestate.com/recipes/440499/)

    使用多态(推荐的方法而不是类型检查对象)

    使用if-elif-else梯形图

    有人甚至推荐了访客模式(可能是外在的)

鉴于选择的种类繁多,我在确定如何处理特定代码时遇到了一些困难.我想学习选择其中一种方法的标准.另外,我很感谢在我遇到麻烦的具体情况下做什么的建议(对选择的解释).

这是具体问题:
(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 ...

(2)
第二段代码是当用户改变曲线属性时调用的qt-slot.基本上,槽从gui(spinBox)获取数据并将其放入适当曲线类的实例变量中.在这种情况下,我再次有同样的问题 - 我应该使用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  

供参考,以下是连接上述插槽的代码 -

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等在构造函数中初始化.

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

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



1> S.Lott..:

叹.对问题的错误部分过分绞尽脑汁.switch语句不是问题.表达"替代"的方法有很多,不能增加意义.

问题是意义 - 而不是技术陈述的选择.

有三种常见的模式.

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

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

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

其他一切都只是棘手的代码,可以达到类似的效果.

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

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

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


@batbrat:只是为了确定 - 两年后,其他人会阅读该代码并询问"他们**的意思是什么**?" 使意思如此清晰,你不必回答任何人的问题.软件捕获知识.尽可能清楚地表达这些知识.

2> dF...:

在第一个例子中,我肯定会坚持使用if-else语句.事实上我没有理由不使用if-else除非

    您发现(使用例如配置文件模块)if语句是一个瓶颈(非常不可能的IMO,除非您有大量的案例做得很少)

    使用字典的代码更清晰/重复次数更少.

你的第二个例子我实际上会重写

setattr(self, name, value)

(可能添加一个断言语句来捕获无效名称).

推荐阅读
谢谢巷议
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有