1

だから私はコードをレビューしているときにこの興味深い問題に遭遇しました:

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')

独自のカスタマイズされたバージョンへのアサーションのラッピングがassert hasattr(...)、属性が存在し、Noneではないことを確認する必要があるたびに使用するよりも高速で優れたソリューションであるかどうか疑問に思いますか?

4

1 に答える 1

2

NameErrorに変更しない限り、最後の行が上がります

self.assert_foo('doo')

assertそれはさておき、ラッパーの有無にかかわらず、上記のコードで使用する必要はないと思います。修正された行は、設定されていることのみをチェックし、設定されself.foo_dooいないことはチェックしませんNone

if self.foo_doo is not None:

両方を行います。

簡略化されたルックファースト属性チェックが必要な場合は、次のように記述できます。

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本番コードでは、コードのユーザーによって影響を受ける実行時の状態ではなく、内部ロジックをチェックするためにのみ使用する必要があります。ユーザーはアサーションを削除または無効にできるため、コードが解放された後の適切な動作については、アサーションに依存しないでください。

上記のコードでは、は何か__init__に設定self.foo_dooされていますが、呼び出し元は後で属性を削除できます。したがって、属性の存在と値はどちらもユーザーが決定した実行時の条件であり、アサーションの適切な対象ではありません。

TestCase.assertXxxメソッドはunittestテストにのみ使用され、失敗した場合は、単純なをラップするだけではありませんassert

于 2012-05-28T23:50:34.223 に答える