为什么装饰器功能缺少f参数?

时间:2018-01-18 13:54:10

标签: python flask

更新:

class Flask():
 def route(self,rule,**options):#why here doesn't exist a paramter to receive the decorated function?
    def wrapper(f):
        endpoint = options.pop('endpoint',None)
        self.add_url_rule(rule,endpoint,f,**option)
        return f
    return wrapper

@app.route('/grade',methods=['post'])
def example():
        pass

为什么路由功能没有接收修饰函数的参数 - 例如

就像典型的例子在python

中使用装饰器一样
def my_decorator(f):# the my_decorator function has got a parameter to receive  the decorated function

     def wrapper(*args, **kwds):
         print('Calling decorated function')
         return f(*args, **kwds)
     return wrapper

@my_decorator
def example():
     """Docstring"""
     print('Called example function')

2 个答案:

答案 0 :(得分:1)

这可能是一个不天真的概念,但要构建一个带有参数的装饰器,你正在编写一个生成装饰器的装饰器。为了让你在那里让我花几个字。

对于简单的装饰者,您通常会按照报告的方式进行:

def decorator(function):
    def wrapper(*args, **kwargs):
        print("bar")
        function(*args, **kwargs)
    return wrapper

@decorator
def foo(word):
    print(word)

foo('boo')

结果

"bar"
"boo"

其中foo在包装内执行,作为'值'变量function的变量,它是通过注释@decorator本身的平均值来指定的 - 没有输入。

鉴于此,如果你想要装饰器输入,你需要发出另一个级别,捕获输入并将其包装到一个闭包中 - 这是装饰器的实际声明,包装函数。这就是烧瓶代码中发生的事情。

def decorator_factory(*a, **kw):
    def decorator(function):
        def wrapper(*args, **kwargs):
            print(a[0])
            function(*args, **kwargs)
        return wrapper
    return decorator

@decorator_factory('bar')
def foo(word):
    print(word)

foo('boo')

再次出现

"bar"
"boo"

答案 1 :(得分:0)

它不是接收装饰函数的Flask.route函数,而是一个名为decorator的函数。这就是如何通过额外的函数调用将路由规则提供给装饰器的方法。如果你仔细观察,你会看到你的典型装饰者的例子"在多个地方被打破,因此是一个错误的例子来比较。修复编译错误后,它会产生以下运行时错误:

def decorator(func):
  def wrapper():
    x = func()
    return x
  return wrapper

@decorator()
def balabala():
  pass

...

TypeError: decorator() missing 1 required positional argument: 'func'

这是因为你在没有参数的情况下调用它。

以这种方式定义的装饰器并不适用于括号,正确的方法是:

@decorator # no brackets here
def balabala():
  pass