Подтвердить что ты не робот

Изменение источника python во время работы

Можно ли изменить исходный файл python во время запуска приложения и немедленно ли это изменить в приложении?

Скажем, у меня есть файл foo.py с классом Foo. В другом модуле я вызываю функции в действии пользователя Foo. Теперь я хотел бы изменить источник Foo без перезапуска приложения и на следующем входе пользователя посмотреть результаты нового кода.

Возможно ли это?

4b9b3361

Ответ 1

Да, но это плохо советовало — код, который сам изменяется (хотя и необходим в некоторых случаях), как правило, трудно отлаживать. Вы ищете метод reload. Способ, которым вы могли бы работать, состоял в том, чтобы изменить исходный файл, а затем вызвать перезагрузку модуля, а затем повторить.

У вас есть возможность повторно назначать и изменять код внутри самого приложения — то, что не подвергает риску условия гонки, и это также обеспечит более последовательную и проверяемую среду. Например, я бы пересчитал Ignacio Vazquez-Abrams answer.


Вы пытались понять, что вам удалось, просто изменив состояние (внешний файл конфигурации, запись в базу данных и т.д.).

Ответ 2

Следующий модуль, вероятно, может изменить все, что вам нужно, а не использовать его, кроме как гасить:)

Обратите внимание, что он не изменит ваш источник, что, вероятно, будет катастрофой, особенно если вы сделаете ошибку кодирования. "Безопасный" вариант - играть с byteplay

http://wiki.python.org/moin/ByteplayDoc

Хорошо, теперь играй! Скажем, мы хотим изменить функцию, чтобы напечатать ее аргументы в обратном порядке. Для этого мы добавим код операции ROT_TWO после того, как два аргумента были загружены в стек. Посмотрите, насколько это просто:

>>> from byteplay import *
>>> from pprint import pprint
>>> def f(a, b):
...     print (a, b)
...
>>> f(3, 5)
(3, 5)
>>> c = Code.from_code(f.func_code)
>>> c.code[3:3] = [(ROT_TWO, None)]
>>> f.func_code = c.to_code()
>>> f(3, 5)
(5, 3)
>>> f(3, 5)
(5, 3)

Если вы используете определенный набор параметров, но хотите сохранить один и тот же вызов функции, вы также можете сделать что-то вроде следующего

class Foo(object):
     def fn(self):
         pass
     def op1(self):
         print "HELLO"
     #etc

>>> a = Foo()
>>> a.fn()
>>> a.fn = a.op1
>>> a.fn()
HELLO