我设计了一个验证API,其中回调用于检查值。回调签名有两种变体:
def check(self, value):
pass
def check(self, value, domain_object):
pass
调用回调实现的示例:
^{pr2}$现在,我在调用方法之前反射性地计算参数的数量,并根据结果向其传递一个或两个参数。但是这种款式好吗?在
会更好吗
check(self, value, domain_object)
或check_with_domain_object
?在我认为在oop方面,始终使用三参数变量是最干净的方法。你怎么认为?在
我喜欢@Space_C0wb0y的答案,它类似于raymondhettinger发送给我的代码,用于解决pyparsing中类似的情况(见下文)。对于您的简单示例,请尝试使用以下normalizer类包装给定的回调:
您的代码现在可以将回调包装在
_ArityNormalizer
中,并且在回调时,总是使用2个参数进行调用。_ArityNormalizer
只执行一次尝试错误的“使用2个参数调用,如果失败,则使用1个参数调用”逻辑,此后将直接转到正确的形式。在在pyparsing中,我希望支持可能被定义为接受0、1、2或3个参数的回调,并编写代码,根据回调函数的签名,用几个修饰符之一包装被调用函数。这样,在运行/回调时,我总是用3个参数进行调用,而装饰器负责使用正确数量的参数进行实际调用。在
我的代码做了很多脆弱的/不可移植的/版本敏感的签名自省来完成这项工作(听起来像是操作目前正在做的),直到raymondhettinger给我一个很好的arity裁剪方法,它基本上实现了@Space_C0wb0y的答案所建议的。RH的代码使用了一些非常简洁的修饰符来包装一个非局部变量来记录成功调用的arity,因此您只需经历一次尝试和错误,而不是每次调用回调。您可以在SourceForge上的pyparsing SVN存储库中的函数
_trim_arity
中看到他的代码—注意,由于使用了“nonlocal”关键字,他的代码有Py2/Py3变体。在上面的
_ArityNormalizer
代码的灵感来自RH的代码,在我完全理解他的代码的魔力之前。在“Space_C0wb0y”使用
try ... except TypError
的想法看起来不错,但我不喜欢这样做会吞并其他异常paulmcguire“对_ArityNormalizer
的建议本质上与一个好的接口是一样的。在最后,我决定让事情尽可能简单和面向对象,并始终使用两个参数,即使在某些情况下第二个参数将不被使用:
实施方:
主叫方:
^{pr2}$最惯用的方法是先尝试两个参数,如果失败,则使用一个:
相关问题 更多 >
编程相关推荐