摘要:事實(shí)上,凡是能通過(guò)邏輯語(yǔ)句來(lái)選擇的事物,都可以通過(guò)查表來(lái)選擇。對(duì)簡(jiǎn)單的情況而言,使用邏輯語(yǔ)句更為容易和直白。但隨著邏輯鏈的越來(lái)越復(fù)雜,查表法也就愈發(fā)顯得更具吸引力。
優(yōu)美勝于丑陋
import this
博客地址:Specific-Dispatch前言
表驅(qū)動(dòng)法是一種編輯模式(Scheme)——從表里面查找信息而不使用邏輯語(yǔ)句(if 和 case)。事實(shí)上,凡是能通過(guò)邏輯語(yǔ)句來(lái)選擇的事物,都可以通過(guò)查表來(lái)選擇。
對(duì)簡(jiǎn)單的情況而言,使用邏輯語(yǔ)句更為容易和直白。但隨著邏輯鏈的越來(lái)越復(fù)雜,查表法也就愈發(fā)顯得更具吸引力。
Python的switch case由于Python中沒有switch case關(guān)鍵詞,所以對(duì)于每一種情況的邏輯語(yǔ)句只能用if,elif,else來(lái)實(shí)現(xiàn),顯得很不Pythonic.
def handle_case(case): if case == 1: print("case 1") elif case == 2: print("case 2") else: print("default case")
而受到PEP-443: Single-dispatch generic functions的啟發(fā),很容易就能實(shí)現(xiàn)如下裝飾器:
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
而之前的代碼就能很優(yōu)美的重構(gòu)成這樣:
@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
而對(duì)于這樣的架構(gòu),即易于擴(kuò)展也利于維護(hù)。
更多實(shí)例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
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/44771.html
摘要:使用閉包實(shí)現(xiàn)私有變量譯者添加未在構(gòu)造函數(shù)中初始化的屬性在語(yǔ)句結(jié)尾處使用分號(hào)在語(yǔ)句結(jié)尾處使用分號(hào)是一個(gè)很好的實(shí)踐。總結(jié)我知道還有很多其他的技巧,竅門和最佳實(shí)踐,所以如果你有其他想要添加或者對(duì)我分享的這些有反饋或者糾正,請(qǐng)?jiān)谠u(píng)論中指出。 showImg(http://segmentfault.com/img/bVbJnR); 如你所知,JavaScript是世界上第一的編程語(yǔ)言(編者注:2...
摘要:什么是重構(gòu)字面上的理解重新組織結(jié)構(gòu)為什么要重構(gòu)原來(lái)的結(jié)構(gòu)是什么樣子的有什么問(wèn)題函數(shù)邏輯結(jié)構(gòu)條件判斷循環(huán)操作包含關(guān)系集合關(guān)系非關(guān)系可擴(kuò)展性差新的變化不能被靈活處理對(duì)象強(qiáng)耦合可復(fù)用性差重復(fù)代碼多性能消耗太多隨著技術(shù)發(fā)展新的好特性如何重構(gòu)知道問(wèn)題 什么是重構(gòu)? 字面上的理解: 重新組織結(jié)構(gòu) 為什么要重構(gòu)? 原來(lái)的結(jié)構(gòu)是什么樣子的?有什么問(wèn)題? 1. 函數(shù)邏輯結(jié)構(gòu)[條件判斷、循環(huán)操作]: 包...
摘要:翻譯正文第一次聲明變量時(shí),請(qǐng)不要忘記使用關(guān)鍵字聲明使用代替空字符串轉(zhuǎn)成布爾值都為每行代碼的末尾最好都加上個(gè)分號(hào)最好給對(duì)象都添加上構(gòu)造函數(shù)在使用和盡量小心。 翻譯介紹 翻譯標(biāo)題:45 Useful JavaScript Tips, Tricks and Best Practices 翻譯來(lái)源:http://modernweb.com/2013/12/23/45-useful-java...
摘要:最近用做了個(gè)單頁(yè)應(yīng)用的項(xiàng)目,頁(yè)面大概有個(gè)左右。詳見鏈接使用自定義事件的表單輸入組件優(yōu)雅解決的問(wèn)題的問(wèn)題由來(lái)已久,在單頁(yè)應(yīng)用中我們免不了需要處理這樣的。 最近用vue+vue-router做了個(gè)單頁(yè)應(yīng)用的項(xiàng)目,頁(yè)面大概有15個(gè)左右。積累了一些開發(fā)經(jīng)驗(yàn)在此做一些記錄.本文主要從可維護(hù)性方面來(lái)考慮SPA的開發(fā)實(shí)踐 全站的顏色定義放在一個(gè)less或者scss的文件里,其他組件和頁(yè)面import...
摘要:最近用做了個(gè)單頁(yè)應(yīng)用的項(xiàng)目,頁(yè)面大概有個(gè)左右。詳見鏈接使用自定義事件的表單輸入組件優(yōu)雅解決的問(wèn)題的問(wèn)題由來(lái)已久,在單頁(yè)應(yīng)用中我們免不了需要處理這樣的。 最近用vue+vue-router做了個(gè)單頁(yè)應(yīng)用的項(xiàng)目,頁(yè)面大概有15個(gè)左右。積累了一些開發(fā)經(jīng)驗(yàn)在此做一些記錄.本文主要從可維護(hù)性方面來(lái)考慮SPA的開發(fā)實(shí)踐 全站的顏色定義放在一個(gè)less或者scss的文件里,其他組件和頁(yè)面import...
閱讀 2137·2021-11-22 15:22
閱讀 1286·2021-11-11 16:54
閱讀 1807·2021-09-23 11:32
閱讀 3007·2021-09-22 10:02
閱讀 1771·2019-08-30 12:59
閱讀 1085·2019-08-29 16:27
閱讀 622·2019-08-29 13:21
閱讀 2464·2019-08-28 17:57