首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用装饰器模块向装饰器传递参数

使用装饰器模块向装饰器传递参数
EN

Stack Overflow用户
提问于 2014-11-12 15:47:17
回答 2查看 163关注 0票数 0

我希望根据范围验证类成员的输入值。我正在尝试装饰模块,因为它提供了所有的好处(比如保存类元数据)。

下面是我的验证装饰师:

代码语言:javascript
复制
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

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

代码语言:javascript
复制
@valid_range({'max_inclusive':1,'min_inclusive':0})
def value_setter(self,value):
    self.value = value

是否有一种方法将max/min dict作为参数传递给我的装饰器(在装饰器定义本身中用作range )?我知道如何使用常规的装饰器来完成这个任务,但是正如我所说的,如果可能的话,我想使用装饰模块。

如果不可能,我如何才能做到这一点,并保存所有的标识数据?我是否应该考虑使用其他模块呢?

编辑:注意,将range dict参数作为*args**kwargs的一部分传递不是一个选项。我不想把它作为我的类定义的一部分。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-11-12 15:58:46

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

代码语言:javascript
复制
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

用法:

代码语言:javascript
复制
@valid_range(10, 20)
def f(x):
    pass
票数 4
EN

Stack Overflow用户

发布于 2014-11-12 17:59:05

想出了下面的解决方案。基本上,我是在用另一个装潢师包装我的装潢师。

这确实允许将max和min从代码的其余部分中分离出来,但这绝对不是一个很好的解决方案,并且忽略了decorator模块的要点(这是为了简化装饰器的应用程序)。出于这个原因,我更喜欢阿库什纳的回答,而不是我自己的答案。

代码语言:javascript
复制
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)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26890976

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档