【问题标题】:python decorator function with arguments带参数的python装饰器函数
【发布时间】:2015-10-19 17:00:24
【问题描述】:

我已经阅读并理解了这篇关于函数装饰器的文章:https://www.artima.com/weblogs/viewpost.jsp?thread=240845 具体来说,我说的是“带有装饰器参数的装饰器函数”部分

不过,我遇到了问题。我正在尝试编写一个带有参数的装饰器函数,以将参数修改为类构造函数。我有两种写法。

首先是一些导入:

import scipy.stats as stats
import numpy as np

方式一(类似于前面文章的例子):

def arg_checker1(these_first_args):
    def check_args(func):
        def wrapped(*args):
            for arg in args[:these_first_args]:
                assert isinstance(arg, np.ndarray) and arg.ndim == 2
            return func(*args) 
        return wrapped
    return check_args

或方式2:

def arg_checker2(these_first_args, func):
    def wrapped(*args):
        for arg in args[:these_first_args]:
            assert isinstance(arg, np.ndarray) and arg.ndim == 2
        return func(*args) 
    return wrapped

我只想在函数的第一个“these_first_args”不是二维 np 数组时抛出错误。但是看看当我尝试使用它时会发生什么(不是用@,而是直接作为一个函数使用)

class PropDens1:
    def __init__(self, samp_fun):
        self.samp = arg_checker1(samp_fun, 2) #right here

class PropDens2:
    def __init__(self, samp_fun):
        self.samp = arg_checker2(2, samp_fun) #right here

q_samp = lambda xnm1, yn, prts : stats.norm.rvs(.9*xnm1,1.,prts)
q1 = PropDens1(q_samp) #TypeError: arg_checker1() takes exactly 1 argument (2 given)
q2 = PropDens2(q_samp) #no error

第二个似乎与几个例子一起工作。不过,有没有更好的方法来做到这一点?如果没有,为什么会这样?

我想这就是我不明白的原因。这是该链接论文中的示例:

def decoratorFunctionWithArguments(arg1, arg2, arg3):
    def wrap(f):
        print "Inside wrap()"
        def wrapped_f(*args):
            print "Inside wrapped_f()"
            print "Decorator arguments:", arg1, arg2, arg3
            f(*args)
            print "After f(*args)"
        return wrapped_f
    return wrap

为什么他实际上不必将要包装的函数(在本例中为 f)作为参数传递给 decoratorFunctionWithArguments()?

【问题讨论】:

  • 我对您的某些代码在方式 1 中的缩进感到有些困惑。你能再检查一下吗?
  • @bcdan 缩进已修复。

标签: python decorator


【解决方案1】:

例外是告诉你到底哪里出了问题。你用 2 个参数调用 arg_checker1,但你只用一个参数定义了它。你应该写:

self.samp = arg_checker1(2)(samp_fun)

这有点等价于:

@arg_checker1(2)
def q_samp(...):
    ...

无论如何,你的方式 1 是要走的路,因为它可以在 @ 语法下正常工作。

【讨论】:

  • 这是假设您的returns 在“方式 1”中缩进很好,否则您也必须修复它。
  • 缩进已修复。是的,我知道问题出在哪里,但我从来没有想过要做双括号的事情。非常简洁。很好,谢谢。
  • 第二个括号是对check_args 的调用,由arg_checker1 返回。
猜你喜欢
  • 2014-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-03
  • 2014-03-24
  • 1970-01-01
  • 2016-09-27
相关资源
最近更新 更多