Зависит от того, что сделал патч. Monkeypatching - это не что-то особенное, это просто присвоение имени другому объекту. Если больше ничего не ссылается на старое значение, значит оно ушло из памяти Python.
Но если код, который пропатчил имя, сохранил ссылку на исходный объект в виде другой переменной, то исходный объект все еще должен быть «восстановлен»:
import target.module
_original_function = target.module.target_function
def new_function(*args, **kwargs):
result = _original_function(*args, **kwargs)
return result * 5
target.module.target_function = new_function
Здесь имя target_function
в пространстве имен модуля target.module
было связано с указанием на new_function
, но исходный объект все еще доступен как _original_function
в пространстве имен кода исправления.
Если это сделано в функции, то оригинал может быть доступен как замыкание . Для вашего конкретного примера вы можете получить оригинал с:
FilterExpression.resolve.__closure__[0].cell_contents
или, если вы предпочитаете доступ по имени:
def closure_mapping(func):
closures, names = func.__closure__, func.__code__.co_freevars
return {n: c.cell_contents for n, c in zip(names, closures)}
original_resolve = closure_mapping(FilterExpression.resolve)['original_resolve']
В противном случае вы можете указать Python перезагрузить исходный модуль с importlib.reload()
:
import target.module
importlib.reload(target.module)
Это обновляет пространство имен модуля, «сбрасывая» все глобальные имена к тому, что они были установлены во время импорта (все дополнительные имена сохраняются).
Обратите внимание, однако, что любой код, содержащий прямую ссылку на пропатченный объект (такой как ваш объект класса), не будет видеть обновленные объекты! Это связано с тем, что from target.module import target_function
создает новую ссылку на объект target_function
в текущем пространстве имен, и никакая повторная загрузка исходного модуля target.module
не обновляет другие прямые ссылки. Вам придется обновить эти другие ссылки вручную или перезагрузить их пространства имен.