Pythonで共用されるモジュールの一部の関数だけ実行時に差し替えたい

投稿者: Anonymous

環境
Windows10 Pro 64bit
Python 3.6.1

下記のモジュール構成だったとします。

main.py
A/
    __init__.py
    a.py
    b.py

A.a.func()はA.bでも使用されていますが、バグがあり修正する必要があります。ただし、モジュールA内のソースコード(A.a.py, A.b.py)はできれば編集したくありません。

そのため、main.py内で、A.bが使用するA.a.funcだけを差し替えたいのです。
しかし、main.py内で下記のように置き換えても、main.py内では置き換わりますが、A.b内で使用されるA.a.func()は置き換えることができませんでした。

# main.py
import A.a

def custom_func():
    return 0

setattr(A.a 'func', custom_func)

# A/b.py
from .a import func

func()      # <= 置き換わっていない

何か方法はないでしょうか?

解決

setattr を使うことで差し替えることが可能でしたよ。
推測としては setattr(A.a 'func', custom_func) の実行よりも前に、 A.b をうっかりimportしてしまっているコードがあるのでは? という印象です。

main.py

import A.a


A.a.f()  # => 'a!'が出力


def custom_func():
    print('custom!!')


setattr(A.a, 'f', custom_func)

from A.a import f

f()  # => 'custom!'が出力

import A.b  # => 'custom!'が出力

A/a.py

def f():
    print('a!')

A/b.py

from .a import f


f()
回答者: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *