这个问题与我的代码无关
我只想说明我需要对function.func_name
我在代码中使用curry
装饰器
我通过修改func_name来显示curried参数
因此,当我需要一些调试时,我可以很容易地找出哪些参数已被咖喱
>> My modified version <<
>> The original version <<
我的curry
示例:
@curry
def f(a, b, c, flag_foo=True, flag_bar=False):
pass
>>> f
<function f at 0x100545398>
>>> f(1, flag_bar=True)
<function f(1, flag_bar=True) at 0x1005451b8>
>>> f(1, flag_bar=True)(3, flag_foo=False)
<function f(1, 3, flag_foo=False, flag_bar=True) at 0x1004aee60>
由于在没有调试的情况下永远不会访问func_name
,所以
我想避免评估func_name
但是,function
是一个不能被子类化的最终类
有没有办法对function.func_name
进行延迟评估?
欢迎任何建议
答案 0 :(得分:1)
代码:
class Curried(object):
def __init__(self, func, args=None, kwargs=None):
self._func = func
self._args = () if args is None else args[:]
self._kwargs = {} if kwargs is None else dict(kwargs)
self._name = None
def __call__(self, *args, **kwargs):
if args or kwargs:
return Curried(self._func,
self._args + args,
dict(self._kwargs.items() + kwargs.items()))
else:
return self._func(*self._args, **self._kwargs)
def __str__(self):
if self._name is None:
self._name = self._get_curried_name()
return self._name
def _get_curried_name(self):
_args = ([str(a) for a in self._args] +
['{}={}'.format(k, v) for k, v in self._kwargs.iteritems()])
all_args = ", ".join(_args)
return '<curried {}({}) at 0x{:x}>'.format(
self._func.func_name, all_args, id(self))
def curry(func):
_curried = Curried(func)
return _curried
测试:
@curry
def f(a, b, c, flag_foo=True, flag_bar=False):
return 'horray!'
print f
print f(1, 2, flag_bar=True)
print f(1, 2, flag_bar=True)(3, flag_foo=False)
print f(1, 2, flag_bar=True)(3, flag_foo=False)()
结果:
<curried f() at 0x100484210>
<curried f(1, 2, flag_bar=True) at 0x100484250>
<curried f(1, 2, 3, flag_bar=True, flag_foo=False) at 0x100484310>
horray!
这里有一个可调用的类,而不是“纯”函数。您只评估一次名称。当然,如果您需要func_name
,可以将此类变量添加为property
并返回str(self)
,这将被评估一次