我有一个与我合作的界面来声明几种验证方法。为简单起见,我们可以考虑三种方法。 verify_less_than()
,verify_equal()
和verify_less_than_equal(
)。 (参见下面的实施)。当我导入这些时,我想装饰它们,如果验证失败 - verify_less_than( 10, 5 )
- 将引发异常。
我已经让这个工作在前两个,但第三个功能给了我一个更难的时间。因为verify_less_than_equal
是根据前两种方法定义的,如果第一次调用失败 - verify_less_than_equal( 5, 5 )
- 在调用第二次调用之前将抛出异常。
非常感谢对此的任何帮助
示例代码:
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 ) )
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
答案 0 :(得分:2)
您可以定义将保留未修饰的私有(下划线)方法,以便_verify_less_than_equal
可以调用未修饰的函数。 for-loop
然后可以添加公共API(没有下划线的方法),它们是私有方法的装饰版本:
import types
def add_decorators(cls):
def decorate(fn):
def wrapped(self, x, y):
res = fn(self, x, y)
if not res:
raise ValueError('Verification failed! {}({}, {}) is False'
.format(fn.__name__, x, y))
return res
return wrapped
for k, v in vars(cls).items():
if isinstance(v, types.FunctionType):
if k.startswith('__'): continue
if k.startswith('_'):
setattr(cls, k[1:], decorate(v))
return cls
@add_decorators
class NeedsDecoration():
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)
def __init__(self): pass
verifier = NeedsDecoration()
assert verifier.verify_less_than_equal(5, 5)
根据需要,最后一行不会引发异常。