0

プライベートでクラスの一部である関数にモンキー パッチを適用したいが、パッチを適用した関数も呼び出したい。

例:

class SomeClass:
    def __some_function(self, foo):
        return do_something()

今、私は次のようなものを書きたい

def new_function(self, foo)
    if foo == 'bar':
        return True
    return super(self).__some_function(foo)

SomeClass.__some_function = new_function

これをデコレータで上書きしようとしましたが、アクセスできないため、古い関数を呼び出すのに問題がありました。また、モックライブラリをチェックしましたが、パラメータを指定して古い関数を呼び出す方法がわかりませんでした。


私が試したデコレータ:

def patch_something(method):
    def new_function(self, foo):
        if foo == 'bar':
            return True
        return method(self, foo)
    return new_function

SomeClass.__some_function = patch_something(SomeClass.__some_function)

このエラーが発生します (クラスが別のファイルにあります - これは問題ですか?)。

AttributeError: type object 'SomeClass' has no attribute '__some_function'
4

1 に答える 1

2

アンダースコアが 2 つある属性は、マングルされた名前であり、ドキュメント__で説明されているように、マングルされた名前でアクセスする必要があります。

クラス プライベート メンバーには有効なユースケースがあるため (つまり、サブクラスによって定義された名前と名前の衝突を避けるため)、名前マングリングと呼ばれるそのようなメカニズムのサポートは制限されています。__spam (少なくとも 2 つの先頭のアンダースコア、多くても 1 つの末尾のアンダースコア) の形式の識別子は、原文で _classname__spam に置き換えられます。ここで、classname は先頭のアンダースコアを取り除いた現在のクラス名です。このマングリングは、クラスの定義内で発生する限り、識別子の構文上の位置に関係なく行われます。

于 2016-06-21T12:08:16.550 に答える