使用 Python 实现简单的 switch/case 语句的方法


Posted in Python onSeptember 17, 2018

在Python中是没有Switch / Case语句的,很多人认为这种语句不够优雅灵活,在Python中用字典来处理多条件匹配问题字典会更简单高效,对于有一定经验的Python玩家不得不承认,的确如此。

但今天我们还是来看看如果一定要用Python来Switch / Case,可以怎么玩。

语法约束

我们先定义一下Switch/Case应该怎么表达,为了简单我们可以让它长成这样。

def cn():
  print('cn')
def us():
  print('us')
switch(lang).case('cn',cn)
truetruetrue.case('us',us)
   .default(us)

类实现一

通过以上约束,我们可以把switch当成一个类来实现,传入的参数在构造函数里处理,然后再分别实现case和default方法即可。

class switch(object):
  def __init__(self, case_path):
    self.switch_to = case_path
    self._invoked = False
  def case(self, key, method):
    if self.switch_to == key and not self._invoked:
      self._invoked = True
      method()
    return self
  def default(self, method):
    if not self._invoked:
      self._invoked = True
      method()

在构造函数中我们记住了 case_path 和执行状态 _invoked ,在 case() 里如果当前的 key 和 switch_to 匹配并且函数没有被执行过,那么就更新 _invoked 并执行对应的方法。在 default() 里检查一下 _invoked ,如果从没执行过,那么就调用 default 分支的函数。

看上去还不错,我们来试用一下。

switch('cn').case('cn',cn).case('us',us).default(fail)
>>> cn
switch('us').case('cn',cn).case('us',us).default(fail)
>>> cn
switch('jp').case('cn',cn).case('us',us).default(fail)
>>> fail
switch('cn').case('cn',cn).case('us',us)
>>> cn

让我们来看几个奇葩一点的case。

# duplicate case
switch('us').case('us',cn).case('us',us).default(fail)
>>> cn
def cn() return 'cn'
def us() return 'us'
# return value
result = switch('cn').case('cn',cn).case('us',us)
result
>>> <python_switch_case.switch object at 0x11034fb70>

发现了没有,上面的实现不会处理重复的case,当然你可以加强一下case方法,最好是抛出异常,其他编程语言通常都这样做。

第二个问题,你希望从case里拿到返回值,像上面的写法是没希望了,因为扔掉了。我们可以考虑在switch类里加一个result的变量来保存执行结果。

class switch(object):
  def __init__(self, case_path):
    ...
    self.result = None
  def case(self, key, method):
    ...
    self.result = method()
  ...

在调用结束后,就可以通过 result 拿到结果了。

_ = switch('cn').case('cn',cn).case('us',us)
_.result
>>> cn

类实现二

我大概在网上搜了一下,你还可以参考 Brian Beck 通过类来实现Swich/Case。

class switch(object):
  def __init__(self, value):
    self.value = value
    self.fall = False
  def __iter__(self):
    """Return the match method once, then stop"""
    yield self.match
    raise StopIteration
  def match(self, *args):
    """Indicate whether or not to enter a case suite"""
    if self.fall or not args:
      return True
    elif self.value in args:
      self.fall = True
      return True
    else:
      return False
c = 'z'
for case in switch(c):
  if case('a'): pass # only necessary if the rest of the suite is empty
  if case('c'): pass
  # ...
  if case('y'): pass
  if case('z'):
    print("c is lowercase!")
    break
  if case('A'): pass
  # ...
  if case('Z'):
    print("c is uppercase!")
    break
  if case(): # default
    print("I dunno what c was!")

这种实现相对复杂一点,而且用起来也不是很舒服,又需要for又需要if(还不如直接if/else痛快)。当然也有好处,就是可以把相同结果的case放一起,而且case里可以写更多东西,不仅仅是一个方法名。

写在最后

最后我们还是回到Python推崇的方法来处理switch/case问题,一般我们可以通过字典来处理这种多分支的问题,举例说明。

MAPPING = {
  'cn': cn,
  'us': us
}
lang = 'cn'
result = MAPPING.get(lang, default=us)

是不是一目了然,不仅易于阅读也易于维护。在字典中key是唯一的,value可以是任意类型的数据,可以是类或者是方法,所以足够灵活。

下面通过代码再次学习python语言switch-case

 初学python语言,竟然很久才发现python没有switch-case语句,查看官方文档说是可以用if-elseif-elseif。。。。代替。

讲真,这都不是问题。不就是一个条件判断吗。用if-elseif-.......肯定没问题,同时也用其他的解决方案,比较简单的就是利用

字典来实现同样的功能。写一个字典,每个key对应的值是一个方法。如switch =

{"valueA":functionA,"valueB":functionB,"valueC":functionC}

调用时可以像这样

try:
switch["value"]() #执行相应的方法。
except KeyError as e:

pass 或 functionX #执行default部分

简单代码如下:

switch = {
   "a":lambda x:x*2,
   "b":lambda x:x*3,
   "c":lambda x:x**x
 } 
 try:
   swtich["c"](6)
 except KeyError as e:
   pass

如果不嫌麻烦自己写一个swtich类来实现也没问题......不过真有这个必要吗

总结

以上所述是小编给大家介绍的使用 Python 实现简单的 switch/case 语句的方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Python 相关文章推荐
下载糗事百科的内容_python版
Dec 07 Python
Python中使用Beautiful Soup库的超详细教程
Apr 30 Python
Django框架中数据的连锁查询和限制返回数据的方法
Jul 17 Python
python中使用序列的方法
Aug 03 Python
详解python并发获取snmp信息及性能测试
Mar 27 Python
python+ffmpeg视频并发直播压力测试
Mar 06 Python
解决python3 HTMLTestRunner测试报告中文乱码的问题
Dec 17 Python
关于tf.nn.dynamic_rnn返回值详解
Jan 20 Python
使用matlab 判断两个矩阵是否相等的实例
May 11 Python
django模板获取list中指定索引的值方式
May 14 Python
Python JSON常用编解码方法代码实例
Sep 05 Python
只用50行Python代码爬取网络美女高清图片
Jun 02 Python
深入理解Python中的 __new__ 和 __init__及区别介绍
Sep 17 #Python
python实现简单http服务器功能
Sep 17 #Python
python实现自动登录
Sep 17 #Python
python发送告警邮件脚本
Sep 17 #Python
python实现zabbix发送短信脚本
Sep 17 #Python
python通过zabbix api获取主机
Sep 17 #Python
Python从ZabbixAPI获取信息及实现Zabbix-API 监控的方法
Sep 17 #Python
You might like
比较时间段一与时间段二是否有交集的php函数
2011/05/31 PHP
PHP Session机制简介及用法
2014/08/19 PHP
PHP实现的分页类定义与用法示例
2017/07/05 PHP
PHP实现数组的笛卡尔积运算示例
2017/12/15 PHP
PHP实现笛卡尔积算法的实例讲解
2019/12/22 PHP
tp5框架使用cookie加密算法实现登录功能示例
2020/02/10 PHP
PHP常量DIRECTORY_SEPARATOR原理及用法解析
2020/11/10 PHP
jquery获取ASP.NET服务器端控件dropdownlist和radiobuttonlist生成客户端HTML标签后的value和text值
2010/06/28 Javascript
javascript将异步校验表单改写为同步表单
2015/01/27 Javascript
jquery中表单 多选框的一种巧妙写法
2015/09/06 Javascript
jQuery实现可关闭固定于底(顶)部的工具条菜单效果
2015/11/06 Javascript
基于Javascript倒计时效果
2016/12/22 Javascript
从零学习node.js之文件操作(三)
2017/02/21 Javascript
d3.js入门教程之数据绑定详解
2017/04/28 Javascript
Angular 4.x+Ionic3踩坑之Ionic3.x pop反向传值详解
2018/03/13 Javascript
浅谈vuepress 踩坑记
2018/04/18 Javascript
express+vue+mongodb+session 实现注册登录功能
2018/12/06 Javascript
JS Array.from()将伪数组转换成数组的方法示例
2020/03/23 Javascript
详解Vue中的自定义指令
2020/12/07 Vue.js
详细探究Python中的字典容器
2015/04/14 Python
Django发送html邮件的方法
2015/05/26 Python
python简单贪吃蛇开发
2019/01/28 Python
解析Python3中的Import
2019/10/13 Python
如何使用python3获取当前路径及os.path.dirname的使用
2019/12/13 Python
python将logging模块封装成单独模块并实现动态切换Level方式
2020/05/12 Python
解决启动django,浏览器显示“服务器拒绝访问”的问题
2020/05/13 Python
Clarks英国官方网站:全球领军鞋履品牌
2016/11/26 全球购物
Omio俄罗斯:一次搜索公共汽车、火车和飞机的机票
2018/11/17 全球购物
Bose加拿大官方网站:美国知名音响品牌
2019/03/21 全球购物
体育活动总结
2015/02/04 职场文书
美术教师个人工作总结
2015/02/06 职场文书
会计求职自荐信
2015/03/26 职场文书
2015年办税服务厅工作总结
2015/07/23 职场文书
python3美化表格数据输出结果的实现代码
2021/04/14 Python
python中super()函数的理解与基本使用
2021/08/30 Python
nginx lua 操作 mysql
2022/05/15 Servers