1. ホーム
  2. python

Pythonで関数からデコレータを除去する方法

2023-08-08 03:41:09

質問

次のようなものがあるとします。

def with_connection(f):
    def decorated(*args, **kwargs):
        f(get_connection(...), *args, **kwargs)
    return decorated

@with_connection
def spam(connection):
    # Do something

をテストしたいのですが spam 関数を、接続の設定(あるいはデコレータが行っていること)の手間をかけずにテストしたいのです。

与えられた spam があったとして、そこからデコレータを取り除き、その下の "undecorated" 関数を取得するにはどうすればよいでしょうか?

どのように解決するのですか?

一般的なケースでは、次の理由で解決できません。

@with_connection
def spam(connection):
    # Do something

def spam(connection):
    # Do something

spam = with_connection(spam)

ということは、オリジナルのスパムはもう存在しないかもしれないということです。(あまり美しくない)ハックはこうなります。

def with_connection(f):
    def decorated(*args, **kwargs):
        f(get_connection(...), *args, **kwargs)
    decorated._original = f
    return decorated

@with_connection
def spam(connection):
    # Do something

spam._original(testcon) # calls the undecorated function