【发布时间】:2013-08-02 01:06:18
【问题描述】:
我有一些函数,在正常情况下,使用用户输入提供的参数调用这些函数。但是,使用某些系列参数调用其中一些函数是有效的,这些参数是在运行时根据某些系统状态确定的。
我希望用户能够可选地指示我的程序使用所有有效输入调用这些函数并返回每个调用的结果。我认为一个装饰器的工作类似于激活开关的功能,它具有另一个装饰器,指示使用哪个系列的参数会很好地工作。
此外,我需要保留函数签名和元数据。这对我的程序的运行至关重要。
这是我尝试过的,但它不起作用。它基于this example。
>>> from decorator import decorator
>>> def the_list():
... return ["foo", "bar", "baz"]
...
>>> import itertools
>>> @decorator
... def do_all(func):
... # this will do nothing (besides wrap in a tuple) unless func is decorated with @gets_arg_from
... if hasattr(func, 'get_from'):
... return tuple(func(*args) for args in itertools.product(*(list_fun() for list_fun in func.get_from)))
... else:
... return (func(),)
...
>>> def gets_arg_from(*list_funcs):
... # this will do nothing to func unless decorated with @do_all
... def gets_arg_from(func, *args, **kwargs):
... func.get_from = list_funcs
... return func(*args, **kwargs)
... return decorator(gets_arg_from)
...
>>> @gets_arg_from(the_list)
... def print_func(word):
... # this will print its argument unless decorated with @do_all
... # at that point it will print every element returned by the_list()
... print word
...
>>> print_func("foo")
foo
>>> all = decorator(do_all, print_func)
>>> all()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: print_func() takes exactly 1 argument (0 given)
>>> print_func.get_from
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'function' object has no attribute 'get_from'
我的预期是:
>>> all()
("foo", "bar", "baz")
我注意到的是错误的:
-
gets_arg_from不会将get_from属性添加到func。 - 关于我使用符号
@gets_arg_from(the_list)是错误的。它认为我正在尝试传递两个参数(但为什么这会成为问题?)
至于我的动机,我想到了装饰器,因为实际上有数百个这样的例程,它们的实现细节(以及它们的功能正确性)经常变化,我不想使用 @987654329 @ 来根据他们的参数名称来推理要做什么,我也不想为每个有意义的函数硬编码 do_all 功能。类方法可能有效,但就我的目的而言,它们是语义设计的。此外,为了其他可能需要维护我的代码的人,我认为让他们应用装饰器而不用担心其余部分更容易,而不是使用某些参数名称或将函数放在某个类中或任何。我意识到这个问题可能听起来很奇怪,所以我想这个脚注可能会让我看起来不像个疯子。
【问题讨论】:
-
你实际上在做什么?这听起来有点像单元测试。你在进行单元测试吗?
-
@user2357112 不,我不是。我正在尝试为具有某些属性(即特定类型的装饰器)的函数进行一种“切换”。
-
我不确定我是否 100% 关注 - 但我最初的想法是你能在这里与
functools.partial合作吗...? -
@JonClements 以什么方式?根据
decoratordocumentation,gets_arg_from和do_all实际上是functools.partials。
标签: python python-2.7 decorator python-decorators