部分应用/和/或/柯里化的装饰器:如何确定是否提供了强制参数?

问题描述

我最近一直在修改装饰器,并且(作为学术练习)尝试实现一个装饰器,允许部分应用和/或装饰函数的柯里化。此外,这个装饰器应该是可选参数化的,并采用一个 kwarg asap 来确定装饰函数是否应该在获得所有必需的 args/kwargs 后立即返回(认:asap=True)或者装饰函数是否应该保留缓存 args/kwargs,直到不带参数调用函数 (asap=False)。

这是我想出的装饰器:

def partialcurry(_f=None,*,asap: bool=True):
    """ Decorator; optionally parameterizable; Allows partial application /and/or/ currying of the decorated function F. Decorated F fires as soon as all mandatory args and kwargs are supplied,or,if ASAP=False,collects args and kwargs and fires only if F is called without args/kwargs. """

    def _decor(f,*args,**kwargs):

        _all_args,_all_kwargs = list(args),kwargs

        @functools.wraps(f)
        def _wrapper(*more_args,**more_kwargs):

            nonlocal _all_args,_all_kwargs # needed for resetting,not mutating
            _all_args.extend(more_args)
            _all_kwargs.update(more_kwargs)

            if asap:
                try:
                    result = f(*_all_args,**_all_kwargs)
                    # reset closured args/kwargs caches
                    _all_args,_all_kwargs = list(),dict()
                except TypeError:
                    result = _wrapper
                return result

            elif not asap:
                if more_args or more_kwargs:
                    return _wrapper
                else:
                    result = f(*_all_args,**_all_kwargs)
                    # again,reset closured args/kwargs caches
                    _all_args,dict()
                    return result

        return _wrapper

    if _f is None:
        return _decor
    return _decor(_f)


### examples
@partialcurry
def fun(x,y,z=3):
    return x,z

print(fun(1))     # preloaded function object
print(fun(1,2))  # all mandatory args supplied; (1,1,2); reset
print(fun(1)(2))  # all mandatory args supplied; (1,2,3); reset

print()

@partialcurry(asap=False)
def fun2(x,z

print(fun2(1)(2,3))  # all mandatory args supplied; preloaded function object
print(fun2())         # fire + reset
print(fun2(1)(2))     # all mandatory args supplied; preloaded function object
print(fun2(4)())      # load one more and fire + reset

我确信这通常可以改进(例如,将它作为一个类来实现是一个好主意)并且非常感谢任何建议,但是我的主要问题是如何确定是否提供了所有强制性参数/kwargs,因为我觉得检查 TypeError 太笼统了,可以捕获所有类型的 TypeError一个想法是定义一个辅助函数来计算强制参数的数量,可能是这样的:

def _required_args_cnt(f):
    """ Auxiliary function: Calculate the number of /required/ args of a function F. """
    
    all_args_cnt = f.__code__.co_argcount + f.__code__.co_kwonlyargcount
    def_args_cnt = len(f.__defaults__) if f.__defaults__ else 0
    return all_args_cnt - def_args_cnt

明显不满意..

非常感谢任何建议!

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)