内容简介:在Python中是没有Switch / Case语句的,很多人认为这种语句不够优雅灵活,在Python中用字典来处理多条件匹配问题字典会更简单高效,对于有一定经验的Python玩家不得不承认,的确如此。但今天我们还是来看看如果一定要用Python来Switch / Case,可以怎么玩。我们先定义一下Switch/Case应该怎么表达,为了简单我们可以让它长成这样。
在 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可以是任意类型的数据,可以是类或者是方法,所以足够灵活。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- SQL语句实现查询Index使用状况
- SQL语句实现查询并自动创建Missing Index
- php实现解析xml并生成sql语句的方法
- Python with语句上下文管理器两种实现方法分析
- MySQL 建表语句转 PostgreSQL 建表语句全纪录
- Go语言开发-过程式编程-通信和并发语句-Select语句
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Algorithms Unlocked
Thomas H. Cormen / The MIT Press / 2013-3-1 / USD 25.00
Have you ever wondered how your GPS can find the fastest way to your destination, selecting one route from seemingly countless possibilities in mere seconds? How your credit card account number is pro......一起来看看 《Algorithms Unlocked》 这本书的介绍吧!