4

このように動作するユーティリティメソッドがあります

def my_patch_method(self):
    pass

def patch_my_lib():
    from mylib import MyClass
    MyClass.target_method = my_patch_method
    return MyClass()

このテストは失敗します:

self.assertEqual(my_patch_method, patch_my_lib().target_method)

これは機能しますが:

self.assertEqual(my_patch_method.__name__, patch_my_lib().target_method.__name__)

パッチメソッドは同じ名前を持っていないので、これはpatch_my_lib()それが支払われたものを実行していることを証明するものとして受け入れられますが、なぜ最初の機能が期待どおりに機能しないのですか?そして、それを「修正」する方法はありますか?

4

4 に答える 4

3

最初のテストが失敗する理由は、関数をクラスにモンキーパッチすると、実際には同じオブジェクトではなくなるためです。

>>> def foo(self): pass
... 
>>> class Foo: pass
... 
>>> Foo.bar = foo
>>> type(Foo.bar)
<type 'instancemethod'>
>>> type(foo)
<type 'function'>
>>> 
>>> Foo.bar is foo
False
>>> Foo.bar == foo
False

実際、元の関数と新しいメソッドには異なるタイプがあります。代わりに、最初のテストでこの状態を確認してください。

>>> Foo.bar.im_func is foo
True

だから多分これ:self.assertIs(my_patch_method, patch_my_lib().target_method.im_func)

于 2012-10-10T15:05:49.910 に答える
2

試す:

self.assertEqual(my_patch_method, patch_my_lib().target_method.im_func)
于 2012-10-10T15:05:06.530 に答える
1

patch_my_libからインスタンスを返すので、関数をバインドされたメソッドと比較します

このようなものは合格するはずです

self.assertEqual(my_patch_method, patch_my_lib().target_method.im_func)

ただし、パッチを適用している動作が機能していることを確認することをお勧めします

于 2012-10-10T15:01:08.823 に答える
0

MyClass.target_method = my_patch_method関数をのクラス関数として設定しますMyClassが、そのクラスのインスタンスを。で返しますreturn MyClass()

于 2012-10-10T15:02:26.070 に答える