Моя проблема заключается в следующем: мне нужно изменить поведение функции, но я не могу получить доступ или изменить файл, в котором находится функция. Я мог бы импортировать его, и мне бы хотелось немного изменить реализацию. Однако, поскольку у меня нет доступа к самому исходному коду, я не могу изменить его напрямую. Я хочу на самом деле изменить реализацию функции, чтобы все другие файлы, которые импортируют, также имели новую функцию. В настоящее время я пытаюсь манипулировать байтами кода атрибута __code__.co_code функции (я знаю, что это очень плохая практика программного обеспечения, но у меня действительно нет выбора). __code__.co_code возвращает серию байтовых символов, что очень непонятно и крайне сложно изменить (я имею в виду, например, как я собираюсь написать код, используя байты??). Я хотел бы добавить в функцию новый объект кода. Есть ли способ сначала преобразовать строку Python, содержащую новую реализацию, в последовательность байтовых символов, а затем безопасно внедрить ее в старую функцию?
Для минимального воспроизводимого примера предположим, что у меня есть следующую функцию:
и я хочу изменить его на:
Мне удалось получить доступ к последовательностям байт-кода атрибута __code__.co_code функции, например:
Код: Выделить всё
def func1():
return 1
code_obj = func1.__code__.co_code
print(code_obj) # prints b'd\x01S\x00'
new_code = b'd\x01S\x00' # copied the original code bytes sequence. How am I going to write `return 0` in bytes?
func1.__code__.co_code = new_code
print(func1)
code_obj2 = func1.__code__.co_code
И выдает такую ошибку:
Код: Выделить всё
Traceback (most recent call last):
File "C:\Program Files\JetBrains\PyCharm 2024.1\plugins\python\helpers\pydev\pydevconsole.py", line 364, in runcode
coro = func()
File "", line 7, in
AttributeError: readonly attribute
Он сообщает мне, что я не могу изменить атрибут __code__.co_code функции. Кроме того, я действительно не знаю, как написать новую реализацию функции (
) в последовательности байтов. Я знаю, что, вероятно, смогу использовать AST, но я также не знаю, как их использовать. Может кто-нибудь мне помочь? Я действительно застрял здесь. (Примечание: я не могу просто затенить старую функцию новой реализацией, потому что я хочу, чтобы другие файлы, которые импортируют библиотеку, также имели изменения. Кроме того, я не хочу устанавливать функцию в модуле с помощью библиотеки импорта; lib.old_function = новая_функция.)
Подробнее здесь:
https://stackoverflow.com/questions/787 ... sign-it-to