python 看懂利用@修饰符代替swich的原理

在知乎上看到个很神奇的方法可以在python中写出swich的效果:

_registered_actions = {}

def action(name):
    def decorator(f):
        _registered_actions[name] = f
        return f
    return decorator

@action("getInfo")
def get_info(data):
    ...

@action("changeName")
def change_name(data):
    ...

def do_action(action_name, data):
    try:
        f = _registered_actions[action_name]
    except KeyError:
        return json.dumps(...)
    else:
        f(data)
        ...

作者:灵剑
链接:https://www.zhihu.com/question/50498770/answer/121288828
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
我自学python还没多久,看的一脸懵逼,不过仔细钻研下,其实不麻烦

这里@修饰符是重点,其次是嵌套函数

首先呢,python没有需要声明函数的前提,所以在你跑起来后,它会自动扫描各个函数,在这个扫描过程中所有的@修饰符都会被执行一次。

根据官方文档:https://www.python.org/dev/peps/pep-0318/

我们可以知道:

@dec2
@dec1
def func(arg1, arg2, ...):
    pass
This is equivalent to:

def func(arg1, arg2, ...):
    pass
func = dec2(dec1(func))
拿知乎代码里的例子变化一下来说就是:

@action
def get_info(data):
    ...
相当于
action(get_info的函数指针)
修饰符还可以自己带参数:

@decomaker(argA, argB, ...)
def func(arg1, arg2, ...):
    pass
This is equivalent to:

func = decomaker(argA, argB, ...)(func)
再拿知乎代码里的例子:

@action("getInfo")
def get_info(data):
    ...
相当于
action("getInfo")(get_info的函数指针)
这就是个标准的嵌套函数,其他@修饰符的功能暂时用不上就不提了

我们继续看例子中的action函数

def action(name):
    def decorator(f):
        _registered_actions[name] = f
        return f
    return decorator
根据嵌套函数的定义,猜也猜的出来:
action("getInfo")(get_info的函数指针)
第一个括号内是外层函数的参数,第二个是内层函数的。

外层函数需要返回内部函数名,不过内部函数其实不一定需要返回值,return f 这句可以不写

这个函数利用两个参数,在最上面的_registered_actions字典里写入了 诸如:"getInfo":get_info函数指针 这样的内容

利用python自动扫描的特性,所有含@action的函数都会被自动写进字典中。

执行程序比较普通,就是调用字典我就不说了。

就像知乎里说的,这个方法其实就是查字典,不过维护起来很直观,我立马试了试:

import cv2
import numpy as np
import PIL.Image as image

_blur_actions = {}


# @修饰符相当于 action(name)(修饰的函数名)
def action(name):
    def decorator(func):
        _blur_actions[name] = func
    # 嵌套函数的外层返回的是内部函数名
    return decorator


@action("blur")
def mean_blur(*args):
    return cv2.blur(*args)


@action("GaussianBlur")
def gaussian_blur(*args):
    return cv2.GaussianBlur(*args)


# 以列表形式返回图片像素值
img = image.open("test.png")
img.show()
# 打散成 array形式,可以被 opencv直接使用
imgMatrix = np.array(img)
imgFlited = _blur_actions['GaussianBlur'](imgMatrix, (5, 5), 0)
# 重组成 PIL可以使用的形式
img2 = image.fromarray(imgFlited)
img2.show()
cv2.waitKey()
cv2.destroyAllWindows()
代码整齐了一些...程序短感觉不出来,长了估计优势就明显了。









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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值