使用decorator modu将参数传递给decorator

2024-05-19 22:10:33 发布

您现在位置:Python中文网/ 问答频道 /正文

我想根据一个范围验证类成员的输入值。我正在尝试decorator模块,因为它提供了所有的好处(比如保留类元数据)。你知道吗

这是我的验证装饰器:

from decorator import decorator

@decorator
def valid_range(f,*args,**kwargs):
    value = args[1]
    inrange = True
    try:
        inrange = (inrange and (value <= range['max_inclusive']))
    except KeyError: pass 
    try:
        inrange = (inrange and (value < range['max_exclusive']))
    except KeyError: pass 
    try:
        inrange = (inrange and (value >= range['min_inclusive']))
    except KeyError: pass
    try:
        inrange = (inrange and (value > range['min_exclusive']))
    except KeyError: pass
    if inrange:
        return f(*args,**kwargs)
    else:
        raise Exception

下面是decorator的应用程序(假设value_setter在某个类的主体中):

@valid_range({'max_inclusive':1,'min_inclusive':0})
def value_setter(self,value):
    self.value = value

有没有办法将max/mindict作为参数传递给我的decorator(它在decorator定义本身中用作range)?我知道如何使用常规的decorator来实现这一点,但是正如我所说的,如果可能的话,我希望使用decorator模块。你知道吗

如果这是不可能的,我怎么能这样做,并保留所有的识别数据?我应该考虑改用其他模块吗?你知道吗

编辑:注意传递rangedict参数作为*args**kwargs的一部分不是一个选项。我不想把它作为我的类定义的一部分。你知道吗


Tags: 模块andvalueargsrangedecoratorpassinclusive
2条回答

您只需编写自己的(缩写示例):

from functools import wraps

def valid_range(min_val=0, max_val=0):
    def deco(f):
        @wraps(f)
        def wrapper(*args, **kwargs):
            val = args[0]
            if min_val <= val <= max_val:
                return f(*args, **kwargs):
            else:
                raise RangeError
        return wrapper
    return deco

用法:

@valid_range(10, 20)
def f(x):
    pass

提出了以下解决方案。基本上,我是包装在另一个装饰我的装饰。你知道吗

这确实允许将max和min的条目与代码的其余部分分开,但这绝对不是一个好的解决方案,并且忽略了decorator模块的要点(这是为了简化decorators的应用)。因此,我更喜欢阿库什纳的答案,而不是我自己的答案。你知道吗

from decorator import decorator

@decorator
def _valid_range(f,*args,**kwargs):
    return f(*args,range = {'max_inclusive':1,'min_inclusive':0},**kwargs)

@decorator
@_valid_range
def valid_range(f,*args,**kwargs):
    range = kwargs.pop('range',None)
    value = args[0]
    inrange = True
    try:
        inrange = (inrange and (value <= range['max_inclusive']))
    except KeyError: pass 
    try:
        inrange = (inrange and (value < range['max_exclusive']))
    except KeyError: pass 
    try:
        inrange = (inrange and (value >= range['min_inclusive']))
    except KeyError: pass
    try:
        inrange = (inrange and (value > range['min_exclusive']))
    except KeyError: pass
    if inrange:
        return f(*args,**kwargs)
    else:
        raise Exception

@valid_range
def value_setter(value):
    print(value)

相关问题 更多 >