断言包装函数

时间:2012-05-28 17:10:10

标签: python-3.x python-2.7 python pep8

所以我在审核代码时遇到了这个有趣的问题:

class Foo:

  def __init__(self, foo_name):
    self.foo_doo = getattr(foo_name, 'foo_lists', None)

  def assert_foo(self, varname):
    assert hasattr(self, 'foo_%s' % varname)

  def foobar(self):
    assert_foo('doo')

想知道如果将断言包装到您自己的自定义版本是更快/更好的解决方案,那么每当您需要确保该属性存在而不是None时使用assert hasattr(...)

1 个答案:

答案 0 :(得分:2)

除非更改为

,否则最后一行将引发NameError
self.assert_foo('doo')

除此之外,我认为无论是否使用包装器,都应该在上面的代码中使用assert。更正的行仅检查self设置了.foo_doo,但不是None

if self.foo_doo is not None:

同时做到了。

如果想要一个缩写的look-first属性检查,可以编写

def has_foo(self, name):
    return hasattr(self, 'foo_'+name)

def foobar(self):
    if has_foo('doo'):

如果您还想进行非None检查,请将has_foo返回更改为:

return getattr(self, 'foo_'+name, None) is not None 

除此之外,生产代码中的assert应仅用于检查内部逻辑,而不是用于受代码用户影响的运行时条件。用户可以删除或禁用断言,因此代码在释放后不应依赖于assert的正确操作。

在上面的代码中,__init__self.foo_doo设置为某些内容,但调用者可以随后删除该属性。因此,属性的存在和值都是用户确定的运行时条件,而不是断言的适当主体。

TestCase.assertXxx的{​​{1}}方法仅用于测试,当它们失败时,它们不仅仅包装一个简单的unittest