python case_Python Switch Case 最佳实践

优美胜于丑陋

import this

前言

表驱动法是一种编辑模式( Scheme )——从表里面查找信息而不使用逻辑语句(if 和 case)。事实上,凡是能通过逻辑语句来选择的事物,都可以通过查表来选择。

对简单的情况而言,使用逻辑语句更为容易和直白。但随着逻辑链的越来越复杂,查表法也就愈发显得更具吸引力。

Python 的switch case

由于 Python 中没有switch case关键词,所以对于每一种情况的逻辑语句只能用if,elif,else来实现,显得很不 Pythonic.

def handle_case(case):

if case == 1:

print('case 1')

elif case == 2:

print('case 2')

else:

print('default case')

from functools import update_wrapper

from types import MappingProxyType

from typing import Hashable, Callable, Union

def specificdispatch(key: Union[int, str] = 0) -> Callable:

"""specific-dispatch generic function decorator.

Transforms a function into a generic function, which can have different

behaviours depending upon the value of its key of arguments or key of keyword arguments.

The decorated function acts as the default implementation, and additional

implementations can be registered using the register() attribute of the

generic function.

"""

def decorate(func: Callable) -> Callable:

registry = {}

def dispatch(key: Hashable) -> Callable:

"""

Runs the dispatch algorithm to return the best available implementation

for the given *key* registered on *generic_func*.

"""

try:

impl = registry[key]

except KeyError:

impl = registry[object]

return impl

def register(key: Hashable, func: Callable=None) -> Callable:

"""

Registers a new implementation for the given *key* on a *generic_func*.

"""

if func is None:

return lambda f: register(key, f)

registry[key] = func

return func

def wrapper_index(*args, **kw):

return dispatch(args[key])(*args, **kw)

def wrapper_keyword(*args, **kw):

return dispatch(kw[key])(*args, **kw)

registry[object] = func

if isinstance(key, int):

wrapper = wrapper_index

elif isinstance(key, str):

wrapper = wrapper_keyword

else:

raise KeyError('The key must be int or str')

wrapper.register = register

wrapper.dispatch = dispatch

wrapper.registry = MappingProxyType(registry)

update_wrapper(wrapper, func)

return wrapper

return decorate

而之前的代码就能很优美的重构成这样:

@specificdispatch(key=0)

def handle_case(case):

print('default case')

@handle_case.register(1)

def _(case):

print('case 1')

@handle_case.register(2)

def _(case):

print('case 2')

handle_case(1) # case 1

handle_case(0) # default case

而对于这样的架构,即易于扩展也利于维护。

更多实例

class Test:

@specificdispatch(key=1)

def test_dispatch(self, message, *args, **kw):

print(f'default: {message} args:{args} kw:{kw}')

@test_dispatch.register('test')

def _(self, message, *args, **kw):

print(f'test: {message} args:{args} kw:{kw}')

test = Test()

# default: default args:(1,) kw:{'test': True}

test.test_dispatch('default', 1, test=True)

# test: test args:(1,) kw:{'test': True}

test.test_dispatch('test', 1, test=True)

@specificdispatch(key='case')

def handle_case(case):

print('default case')

@handle_case.register(1)

def _(case):

print('case 1')

@handle_case.register(2)

def _(case):

print('case 2')

handle_case(case=1) # case 1

handle_case(case=0) # default case

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值