【问题标题】:Understanding scope and *args and **kwargs in decorator function了解装饰器函数中的作用域和 *args 和 **kwargs
【发布时间】:2016-04-20 13:43:30
【问题描述】:

为什么在下面的装饰器示例中wrapper() 函数需要*args**kwargs

def currency(f):
    def wrapper(*args, **kwargs):
        return '$' + str(f(*args, **kwargs))

    return wrapper

class Product(db.Model):

    name = db.StringColumn
    price = db.FloatColumn

    @currency
    def price_with_tax(self, tax_rate_percentage):
        """Return the price with *tax_rate_percentage* applied.
        *tax_rate_percentage* is the tax rate expressed as a float, like "7.0"
        for a 7% tax rate."""
        return price * (1 + (tax_rate_percentage * .01))

传递给price_with_tax(self, tax_rate_percentage) 的参数不是已经在def currency(f) 函数的范围内可用,因此对wrapper() 函数可用吗?

为什么我们不能直接将f() 传递给wrapper()

我只是想了解为什么 wrapper()*args**kwargs 以及两者如何将参数传递给 price_with_tax(self, tax_rate_percentage)

【问题讨论】:

    标签: python function python-2.7 decorator python-decorators


    【解决方案1】:

    包装器接受一个函数作为参数并返回另一个函数。为了使返回的函数尽可能有用(即应用于任何函数或方法),它必须接受任意数量的参数。

    考虑一下装饰器的作用。这个:

    @currency
    def price_with_tax(self, tax_rate_percentage):
        return price * (1 + (tax_rate_percentage * .01))
    

    本质上只是这个的简写:

    def price_with_tax(self, tax_rate_percentage):
        return price * (1 + (tax_rate_percentage * .01))
    price_with_tax = currency(price_with_tax)
    

    也就是说,price_with_tax最终是currency的返回值,所以它也应该是一个至少接受两个参数(selftax_rate_percentage)的函数。

    不过,@currency 可用于装饰许多其他可能采用不同数量的 args 和不同关键字参数的函数,因此像 currency 这样的装饰器通常采用可变参数来处理所有情况。

    【讨论】:

      猜你喜欢
      • 2013-09-25
      • 2018-08-28
      • 2021-07-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-11
      • 2014-04-26
      相关资源
      最近更新 更多