【发布时间】:2014-04-23 04:50:35
【问题描述】:
我正在使用一个接口来声明几种验证方法。为简单起见,我们可以考虑三种方法。 verify_less_than()、verify_equal() 和 verify_less_than_equal()。 (参见下面的实现)。当我导入这些时,我想装饰它们,以便如果验证失败 - verify_less_than( 10, 5 ) - 将引发异常。
我已经为前两个函数工作了,但第三个函数给了我一个更难的时间。因为verify_less_than_equal是根据前两个方法定义的,如果第一个调用失败 - verify_less_than_equal( 5, 5 ) - 在调用第二个之前会抛出异常。
对此的任何帮助将不胜感激
示例代码:
模块.py
>class needs_decoration():
def verify_less_than( self, x, y ):
return( x < y )
def verify_equal( self, x, y ):
return( x == y )
def verify_less_than_equal( self, x, y ):
return( self.verify_less_than( x, y ) or self.verify_equal( x, y ) )
implementation.py
>import types
import module
def decorate( fn ):
def wrapped( self, x, y ):
res = fn( self, x, y )
if res == False:
raise Exception( 'Verification failed!' )
return res
return wrapped
for k, v in vars( module.needs_decoration ).items():
if isinstance( v, types.FunctionType ):
if not '__init__' in str( vars( module.needs_decoration )[ k ] ):
vars( module.needs_decoration )[ k ] = decorate( v )
verifier = module.needs_decoration()
verifier.verify_less_than_equal( 5, 5 ) # This will raise an exception, and I would like it not to
【问题讨论】:
-
您确定要使用异常而不是布尔值吗?
-
如果不深入了解方法的实现方式或查找堆栈以查看您当前是否在另一个修饰调用中,您将无法做您想做的事情。这很快就会变得丑陋。
-
@joel 我绝对是。这有望用于自动化测试设置。因此,当遇到异常时,控制将返回到高级控制器,在那里它可以决定是否应该重新运行失败的测试部分。使用异常使控件更清晰(必须包装每个验证调用 - 数百个 - 只会使测试混乱)。
-
这似乎更容易导致错误而不是修复它们。如果您的代码依赖于验证不抛出这些错误怎么办?
-
@user2357112 如果我们的验证步骤之一失败,我们的测试将被视为失败,因此验证失败后发生的任何事情都无关紧要。通过抛出异常,我们绕过等待直到测试结束(几个小时后),并且可以立即评估情况。