Как имитировать функцию в нескольких модуляхPython

Программы на Python
Ответить
Anonymous
 Как имитировать функцию в нескольких модулях

Сообщение Anonymous »

В настоящее время я работаю над расширением базы стороннего кода. К сожалению, эта база кода тесно связывает get_args со всеми остальными функциями. get_args — это, по сути, просто метод получения глобального объекта _ARGS. Теперь я хотел бы изменить аргументы для одного вызова функции, не изменяя при этом сам глобальный объект.
С этой целью я использовал unittest.mock.patch, чтобы исправьте функцию get_args, и хотя она успешно исправляется в моей целевой функции f, она не преобразуется в функции, вызываемые f, если они находятся в других модулях. Причина, конечно, в том, что я патчю get_args только в модуле с вызываемой функцией f.
Можно ли издеваться над каждым< /em> последующий вызов get_args внутри моего блока with?
Мой текущий подход, возможно, не лучший для решения этой проблемы, поэтому я также открыт для альтернативных решений этой проблемы.
Минимальный воспроизводимый пример:
Мой код main.py:
from argparse import Namespace
import traceback
import unittest.mock

from mod0 import get_args
from mod1 import f1

class _MockCnt:

def __init__(self):
self._args = Namespace(**{
**get_args().__dict__,
'a': 'a',
})

def new_get_args(self):
print("new_get_args was called")
traceback.print_stack()
return self._args

def main():
with unittest.mock.patch('mod1.get_args', new=_MockCnt().new_get_args):
f1()

main()

Модуль mod0:
from argparse import Namespace

_ARGS = None

def get_args():
global _ARGS
if _ARGS is None:
_ARGS = Namespace(a=1, b=2)
return _ARGS

Модуль mod1:
from mod0 import get_args
from mod2 import f2

def f1():
args = get_args()
args.c = 3
print(f"[f1] Args: {args} (id {id(args)})")
f2()

Модуль mod2:
from mod0 import get_args

def f2():
args = get_args()
print(f"[f2] Args: {args} (id {id(args)})")

Результат:
new get_args was called
File "/tmp/main.py", line 26, in
main()
File "/tmp/main.py", line 24, in main
f1()
File "/tmp/mod1.py", line 6, in f1
args = get_args()
File "/tmp/main.py", line 19, in new_get_args
traceback.print_stack()
[f1] Args: Namespace(a='a', b=2, c=3) (id 281472856422576)
[f2] Args: Namespace(a=1, b=2) (id 281472856399392)

Что мне нужно (следы стека не учитывать):
new get_args was called
[f1] Args: Namespace(a='a', b=2, c=3) (id 281472856422576)
new get_args was called
[f2] Args: Namespace(a='a', b=2, c=3) (id 281472856422576)


Подробнее здесь: https://stackoverflow.com/questions/782 ... le-modules
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»