2015-07-28 3 views
0

Я прочитал и понял эту статью о функции декораторах: https://www.artima.com/weblogs/viewpost.jsp?thread=240845 В частности я говорю о разделе «Функция декоратора с Decorator Аргументами»питона функция декоратора с аргументами

Я бег в проблему, хотя , Я пытаюсь написать функцию декоратора с аргументами для изменения аргументов в конструкторе класса. У меня есть два способа написать это.

Первые несколько импорта:

import scipy.stats as stats 
import numpy as np 

Way 1 (аналогично примеру вышеупомянутой статьи в):

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» к функции не являются 2-d 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 

Почему не он на самом деле нужно передать функции, чтобы быть обернутой (е в данном случае) в качестве аргумента в decoratorFunctionWithArguments()?

+1

Я немного смущен отступом некоторого вашего кода в порядке 1 в частности. Не могли бы вы дважды проверить? – bcdan

+0

Исправления @bcdan исправлены. – Taylor

ответ

3

Исключение указывает вам, что именно не так. Вы вызываете arg_checker1 с 2 аргументами, но вы определили его только с одним. Вы должны написать:

self.samp = arg_checker1(2)(samp_fun) 

что несколько эквивалентно:

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

В любом случае, вам путь 1 путь идти, так как он будет работать нормально с синтаксисом @.

+0

Это предполагает, что '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ', иначе вам также придется это исправить. –

+0

Отступы фиксированные. Да, я знал, в чем проблема, но мне никогда не приходило в голову делать двойные круглые скобки. Очень кратки. Приятно, спасибо. – Taylor

+0

Второй парен - это вызов 'check_args', который возвращается' arg_checker1'. –

Смежные вопросы