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

作者:Tech 时间:2021-02-02 09:10:16 

在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 语句的方法网站的支持!

来源:https://betacat.online/posts/2018-09-16/python-switch-case

标签:python,switch,case
0
投稿

猜你喜欢

  • 正则化DropPath/drop_path用法示例(Python实现)

    2022-12-01 21:58:34
  • Python&Matlab实现伏羲八卦图的绘制

    2023-02-01 02:42:39
  • 漂亮的Django Markdown富文本app插件的实现

    2021-08-14 15:23:24
  • pandas按某列降序的实现

    2021-02-19 08:29:44
  • 使用PHP实现微信摇一摇周边红包

    2023-11-14 12:04:22
  • python 划分数据集为训练集和测试集的方法

    2023-01-10 12:18:36
  • Python XML RPC服务器端和客户端实例

    2022-07-26 05:41:57
  • Django后台获取前端post上传的文件方法

    2023-04-11 10:57:26
  • 浅析C# web访问mysql数据库-整理归纳总结

    2024-01-12 17:07:42
  • bootstrap table单元格新增行并编辑

    2024-04-10 16:09:09
  • SQLServer 全文检索(full-text)语法

    2024-01-21 09:08:02
  • Linux 下 Python 实现按任意键退出的实现方法

    2022-08-07 14:22:01
  • js字符串日期yyyy-MM-dd转化为date示例代码

    2023-08-06 16:35:58
  • Python使用xpath实现图片爬取

    2023-07-10 16:45:42
  • 关于图片存储格式的整理(JPEG格式介绍)

    2023-04-05 12:25:37
  • Vue-cli创建项目从单页面到多页面的方法

    2024-05-21 10:17:04
  • 详解vue中async-await的使用误区

    2024-05-09 09:21:06
  • Python实现的爬取百度贴吧图片功能完整示例

    2021-06-30 19:22:13
  • 一文带你了解Go语言中的指针和结构体

    2024-04-25 15:26:20
  • Python flask框架端口失效解决方案

    2021-02-19 23:48:46
  • asp之家 网络编程 m.aspxhome.com