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