使用 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中cPickle用法例子分享
Jan 03 Python
python 3.5实现检测路由器流量并写入txt的方法实例
Dec 17 Python
解决phantomjs截图失败,phantom.exit位置的问题
May 17 Python
Python 多维List创建的问题小结
Jan 18 Python
python自定义函数实现一个数的三次方计算方法
Jan 20 Python
解决Pycharm后台indexing导致不能run的问题
Jun 27 Python
python实现的读取网页并分词功能示例
Oct 29 Python
Python代码生成视频的缩略图的实例讲解
Dec 22 Python
python 读取更新中的log 或其它文本方式
Dec 24 Python
Python imutils 填充图片周边为黑色的实现
Jan 19 Python
浅析python 通⽤爬⾍和聚焦爬⾍
Sep 28 Python
python 实现的IP 存活扫描脚本
Dec 10 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
PHP4在WinXP下IIS和Apache2服务器上的安装实例
2006/10/09 PHP
php实现上传图片保存到数据库的方法
2015/02/11 PHP
PHP简单遍历对象示例
2016/09/28 PHP
PHP Ajax跨域问题解决方案代码实例
2020/08/01 PHP
判断页面是关闭还是刷新的js代码
2007/01/28 Javascript
关于document.cookie的使用javascript
2008/04/11 Javascript
javascript 去字符串空格终极版(支持utf8)
2009/11/14 Javascript
Javascript实现重力弹跳拖拽运动效果示例
2013/06/28 Javascript
JavaScript获取flash对象与网上的有所不同
2014/04/21 Javascript
轻松掌握JavaScript中的Math object数学对象
2016/05/26 Javascript
JS弹出新窗口被拦截的解决方法
2016/08/09 Javascript
基于vue实现多引擎搜索及关键字提示
2017/03/16 Javascript
JS正则验证多个邮箱完整实例【邮箱用分号隔开】
2017/04/19 Javascript
JavaScript数组push方法使用注意事项
2017/10/30 Javascript
vue-cli 引入、配置axios的方法
2018/05/08 Javascript
浅析Vue 生命周期
2018/06/21 Javascript
VUE2.0+ElementUI2.0表格el-table循环动态列渲染的写法详解
2018/11/30 Javascript
通过JQuery,JQueryUI和Jsplumb实现拖拽模块
2019/06/18 jQuery
如何正确理解vue中的key详解
2019/11/02 Javascript
如何在node环境实现“get数据解析”代码实例
2020/07/03 Javascript
js简单粗暴的发布订阅示例代码
2021/01/23 Javascript
使用python将大量数据导出到Excel中的小技巧分享
2018/06/14 Python
ubuntu 18.04搭建python环境(pycharm+anaconda)
2019/06/14 Python
解决jupyter notebook import error但是命令提示符import正常的问题
2020/04/15 Python
使用Python通过oBIX协议访问Niagara数据的示例
2020/12/04 Python
Bogner美国官网:滑雪服中的”Dior”
2018/01/30 全球购物
美国学校用品、教室和教学商店:Discount School Supply
2018/04/04 全球购物
法学研究生自我鉴定范文
2013/12/04 职场文书
小学新学期寄语
2014/04/02 职场文书
《广玉兰》教学反思
2014/04/14 职场文书
2014年群众路线教育实践活动整改措施
2014/09/24 职场文书
乡镇2014法制宣传日活动总结
2014/11/01 职场文书
2015年大学生工作总结
2015/04/21 职场文书
高三英语教学反思
2016/03/03 职场文书
电脑开机弹出documents文件夹怎么回事?弹出documents文件夹解决方法
2022/04/08 数码科技
html5+实现plus.io进行拍照和图片等获取
2022/06/01 HTML / CSS