使用装饰器参数进行切换

时间:2018-11-23 10:38:52

标签: python decorator

在flaks库中,我们可以像开关盒一样使用装饰器。 (我听得懂吗?)

app.route('')

所以...我想用修饰符和参数做一些switch语句,

喜欢:

@color('pink')
def _pink_power(self):
    print("wow")

@color('blue')
@color('red')
def _powerpower(self):
    print("god!!!!")

def input(color):
    I don't know what to do in here..
    if color is pink, print wow!

我花了很长时间才努力弄清楚,但我做不到。您认为不可能吗?

2 个答案:

答案 0 :(得分:2)

这是一种相对简单的方法(尽管我建议您在最后更改input函数的名称,因为它与同名的内置函数冲突):

class color:
    _func_map = {}

    def __init__(self, case):
        self.case = case

    def __call__(self, f):
        self._func_map[self.case] = f
        return f

    @classmethod
    def switch(cls, case):
        cls._func_map[case]()


@color('pink')
def _pink_power():
    print("wow")

@color('blue')
@color('red')
def _powerpower():
    print("god!!!!")


def input(colorname):
    color.switch(colorname)

input('pink') # -> wow
input('blue') # -> god!!!!
input('red')  # -> god!!!!

增强功能

您可以支持使用默认情况,例如C / C ++的switch语句支持,当没有匹配的colorname时将使用这种情况:

class color:
    DEFAULT = '_DEFAULT'
    def _default(): raise ValueError('Unknown color!')

    _func_map = {DEFAULT: _default}

    def __init__(self, case):
        self.case = case

    def __call__(self, f):
        self._func_map[self.case] = f
        return f

    @classmethod
    def switch(cls, case):
        cls._func_map.get(case, cls._func_map[cls.DEFAULT])()

添加到类中的_default()方法在被调用时引发异常:

input('lavender')  # -> ValueError: Unknown color!

不过,您可以通过定义自己的方法来覆盖它:

@color(color.DEFAULT)  # Define custom color default.
def my_default():
    print("loser!")

input('lavender')  # -> loser!

答案 1 :(得分:1)

您... 可以做到这一点,但我不确定这样做是个好主意。

import contextlib

class Colors(object):
    def __init__(self):
        self.__colors = dict()

    def register(self, colorname):
        def wrapper(f):
            @contextlib.wraps(f)
            def wrapper(*args, **kwargs):
                return f(*args, **kwargs)
            self.__colors[colorname] = wrapper
            return wrapper

    def __getitem__(self, item):
        return self.__colors[item]

colors = Colors()

@colors.register("pink")
def _pink_power():
    print("wow")

@colors.register("blue")
@colors.register("red")
def _powerpurple():
    print("god!!!!!")

def input(colorname):
    colors[colorname]()