2015-07-25 4 views
2

Я нашел этот функционал библиотеки программирования Fn, и я нашел следующий код для функции КаррингаФункции выделки с Python сноски модуля

>>> from fn.func import curried 
>>> @curried 
... def sum5(a, b, c, d, e): 
...  return a + b + c + d + e 
... 
>>> sum5(1)(2)(3)(4)(5) 
15 
>>> sum5(1, 2, 3)(4, 5) 
15 

, но когда я запускаю его я получаю

Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/home/adrian/.local/lib/python2.7/site-packages/fn/func.py", line 83, in _curried 
    return curried(partial(func, *args, **kwargs)) 
    File "/home/adrian/.local/lib/python2.7/site-packages/fn/func.py", line 69, in curried 
    @wraps(func) 
    File "/usr/lib/python2.7/functools.py", line 33, in update_wrapper 
    setattr(wrapper, attr, getattr(wrapped, attr)) 
AttributeError: 'functools.partial' object has no attribute '__module__' 

Можно ли решить это?

ответ

-2

Возможно, вы хотите посмотреть на functools.partial. Вы можете избавиться от аннотаций и просто использовать

curried = partial(sum5, 2, 3, 4) 
curried(5, 6) 
+1

Почему нет голоса? Комментарий будет приятным, поэтому я знаю, что улучшить. – hellow

0

wraps поведение отличается Python3 по сравнению с python2 в частности, `update_wrapper``, код будет работать с Python3 как, но вам нужно будет использовать реализацию обертывания от py3 для его работы.

Я бы отчет об ошибке, но в то же время соответствующие функции из functools здесь:

from functools import wraps, partial, WRAPPER_ASSIGNMENTS,WRAPPER_UPDATES 
def update_wrapper(wrapper, 
        wrapped, 
        assigned = WRAPPER_ASSIGNMENTS, 
        updated = WRAPPER_UPDATES): 
    """Update a wrapper function to look like the wrapped function 
     wrapper is the function to be updated 
     wrapped is the original function 
     assigned is a tuple naming the attributes assigned directly 
     from the wrapped function to the wrapper function (defaults to 
     functools.WRAPPER_ASSIGNMENTS) 
     updated is a tuple naming the attributes of the wrapper that 
     are updated with the corresponding attribute from the wrapped 
     function (defaults to functools.WRAPPER_UPDATES) 
    """ 
    for attr in assigned: 
     try: 
      value = getattr(wrapped, attr) 
     except AttributeError: 
      pass 
     else: 
      setattr(wrapper, attr, value) 
    for attr in updated: 
     getattr(wrapper, attr).update(getattr(wrapped, attr, {})) 
    # Issue #17482: set __wrapped__ last so we don't inadvertently copy it 
    # from the wrapped function when updating __dict__ 
    wrapper.__wrapped__ = wrapped 
    # Return the wrapper so this can be used as a decorator via partial() 
    return wrapper 

def wraps(wrapped, 
      assigned = WRAPPER_ASSIGNMENTS, 
      updated = WRAPPER_UPDATES): 
    """Decorator factory to apply update_wrapper() to a wrapper function 
     Returns a decorator that invokes update_wrapper() with the decorated 
     function as the wrapper argument and the arguments to wraps() as the 
     remaining arguments. Default arguments are as for update_wrapper(). 
     This is a convenience function to simplify applying partial() to 
     update_wrapper(). 
    """ 
    return partial(update_wrapper, wrapped=wrapped, 
        assigned=assigned, updated=updated) 

кэрри обертка:

def curried(func): 
    """A decorator that makes the function curried 
    Usage example: 
    >>> @curried 
    ... def sum5(a, b, c, d, e): 
    ...  return a + b + c + d + e 
    ... 
    >>> sum5(1)(2)(3)(4)(5) 
    15 
    >>> sum5(1, 2, 3)(4, 5) 
    15 
    """ 
    @wraps(func) 
    def _curried(*args, **kwargs): 
     f = func 
     count = 0 
     while isinstance(f, partial): 
      print(f) 
      if f.args: 
       count += len(f.args) 
      f = f.func 

     spec = getargspec(f) 

     if count == len(spec.args) - len(args): 
      return func(*args, **kwargs) 

     return curried(partial(func, *args, **kwargs)) 
    return _curried 

Чтобы исправить только curried функция python2 вы может содержать только от WRAPPER_ASSIGNMENTS, что func имеет:

#change this line 

@wraps(func, (attr for attr in WRAPPER_ASSIGNMENTS if hasattr(func, attr))) 
    def _curried(*args, **kwargs): 
     f = func 
     count = 0 
     while isinstance(f, partial): 
      print(f) 
      if f.args: 
       count += len(f.args) 
      f = f.func 

     spec = getargspec(f) 

     if count == len(spec.args) - len(args): 
      return func(*args, **kwargs) 

     return curried(partial(func, *args, **kwargs)) 
    return _curried 
+0

В вашем последнем фрагменте кода есть синтаксическая ошибка. Ты ничего не украшаешь. –

+0

@ LoïcFaure-Lacroix, это не синтаксическая ошибка, это соответствующая часть кода, которую нужно изменить. –