【问题标题】:how can I write a decorator that changes with arguments我如何编写一个随参数变化的装饰器
【发布时间】:2019-08-07 10:52:52
【问题描述】:

我必须编写一个装饰器def,它以validator def 作为参数。如果 validator 返回 true 它应该装饰 main 以执行一些代码,如果它返回 false 它应该打印一个错误。

我试图用 if 语句在装饰器中编写两个 def 以返回两个不同的 def,但它不起作用。

由于在线判断,功能和逻辑必须与我所说的完全一样(验证必须在装饰器之外完成)

这是一个例子:

#define decorator...

def validator(x):
    return x>=0

@decorator(validator)
def f(x):
    return x**0.5

print(f(4)) #should print 2
print(f(-4)) #should print error

【问题讨论】:

  • “我尝试在装饰器中编写两个 def 并使用 if 语句返回两个不同的 def,但它不起作用” - 请在帖子中包含您的尝试
  • 功能和逻辑必须和我说的一模一样(因为在线判断)

标签: python python-decorators


【解决方案1】:

你可以这样做

#define decorator...

def validator(x):
    return x>=0

def deco(validator):
    def decorator(func):
        def wrapper_decorator(*args, **kwargs):
            if validator(*args, **kwargs):
                return func(*args, **kwargs)
            else:
                print("error")
                return 
        return wrapper_decorator
    return decorator


@deco(validator)
def f(x):
    return x**0.5

print(f(4)) #should print 2
print(f(-4)) #should print error

大家回答的答案基本都是正确的。但是,对于您的情况,您需要一个充当验证器的附加函数。因此,您可以添加另一个外部 def 来接收验证器的功能并检查它是否返回 True/False。

【讨论】:

    【解决方案2】:

    装饰器可以写成example

    def hello_decorator(func): 
        def inner1(*args, **kwargs): 
    
            print("before Execution") 
    
            # getting the returned value 
            returned_value = func(*args, **kwargs) 
            print("after Execution") 
    
            # returning the value to the original frame 
            return returned_value 
    
        return inner1 
    
    
    # adding decorator to the function 
    @hello_decorator
    def sum_two_numbers(a, b): 
        print("Inside the function") 
        return a + b 
    
    a, b = 1, 2
    
    # getting the value through return of the function 
    print("Sum =", sum_two_numbers(a, b)) 
    

    你可以把这段代码改写成

    def limit_decorator(func): 
        def internal(arg): 
    
            if (arg >= 0):
                return func(arg) 
    
            else:
                raise Exception("false input")
    
        return internal 
    
    
    @limit_decorator
    def square_root(a): 
        return a * 0.5
    
    a = -5
    
    print("Sum =", square_root(a)) 
    

    【讨论】:

    • 问题是我发送的代码是要在线判断的,所以我无法重写代码。装饰器必须完全按照我说的定义
    【解决方案3】:

    我建议对 x 进行验证,在嵌套函数上使用一层(基本上将验证器函数合并到装饰器中)

    
    def deco(f):
        def wrapper(x):
            if x<=0:
                return False
            else:
                return f(x)
        return wrapper
    
    
    @deco
    def f(x):
        return x**0.
    
    f(1) #returns false
    f(4) #returns 2.0
    

    【讨论】:

    • 谢谢你的回答,但代码的功能必须和我说的一样,因为它会在线判断
    【解决方案4】:

    试试这个:

    def decorator(validator):
        def subdecorator(function):
            def actual_function(arg):
                if not validator(arg):
                    raise ValueError(f"Bad data: {arg}")
                return function(arg)
            return actual_function
        return subdecorator
    

    【讨论】:

      猜你喜欢
      • 2015-10-22
      • 2015-03-22
      • 1970-01-01
      • 2017-07-17
      • 2021-09-17
      • 1970-01-01
      • 1970-01-01
      • 2021-11-23
      相关资源
      最近更新 更多