Обновление / перезагрузка Python - PullRequest
27 голосов
/ 04 октября 2009

Это очень простой вопрос, но я не смог найти ответ с помощью поиска в Интернете.

Я использую python для управления ArcGIS, и у меня есть простой скрипт на python, который вызывает некоторый заранее написанный код.

Однако, когда я делаю изменения в предварительно написанном коде, это не приводит к каким-либо изменениям. Я импортирую этот модуль и попытался обновить его, но ничего не происходит.

Я даже переместил вызываемый файл в другое место, и скрипт все еще работает нормально. Одна вещь, которую я сделал вчера, - я добавил папку, в которой все мои файлы python находятся в пути sys (с помощью sys.append ('path')), и мне интересно, если это изменило ситуацию.

Заранее спасибо и извините за неаккуратную терминологию.

Ответы [ 7 ]

32 голосов
/ 04 октября 2009

Непонятно, что вы имеете в виду под «обновить», но нормальное поведение Python заключается в том, что вам нужно перезапустить программное обеспечение, чтобы оно по-новому взглянул на модуль Python и перечитал его.

Если ваши изменения не были учтены даже после перезапуска, то это связано с одной из двух ошибок:

  1. Временная метка в pyc-файле неверна и некоторое время в будущем.
  2. Вы на самом деле редактируете не тот файл.

Вы можете с reload перечитать файл даже без перезапуска программного обеспечения с помощью команды reload (). Обратите внимание, что любая переменная, указывающая на что-либо в модуле, должна быть повторно импортирована после перезагрузки. Примерно так:

import themodule
from themodule import AClass

reload(themodule)
from themodule import AClass
19 голосов
/ 04 октября 2009

Один из способов сделать это - позвонить reload.

Пример: Вот содержимое foo.py:

def bar():
    return 1

В интерактивном сеансе я могу сделать:

>>> import foo
>>> foo.bar()
1

Затем в другом окне я могу изменить foo.py на:

def bar():
    return "Hello"

Вернувшись в интерактивный сеанс, вызов foo.bar() по-прежнему возвращает 1, пока я не сделаю:

>>> reload(foo)
<module 'foo' from 'foo.py'>
>>> foo.bar()
'Hello'

Вызов reload - это один способ убедиться, что ваш модуль обновлен, даже если файл на диске изменился. Это не обязательно самый эффективный (вам лучше проверить время последнего изменения файла или использовать что-то вроде pyinotify перед вами reload), но это, безусловно, быстро реализовать.

Одна из причин, по которой Python не читает из исходного модуля каждый раз, заключается в том, что загрузка модуля (относительно) дорога - что, если у вас был модуль 300 КБ, и вы просто использовали одну константу из файла? Python загружает модуль один раз и сохраняет его в памяти, пока вы не reload.

3 голосов
/ 13 марта 2016

Если вы работаете в оболочке IPython, то существуют некоторые магические команды.

Документы IPython охватывают эту функцию, которая называется расширение автозагрузки .

Первоначально я нашел это решение в блоге Джонатана Марча на эту тему (см. Пункт 3 по этой ссылке).

По сути, все, что вам нужно сделать, это следующее, а сделанные вами изменения автоматически отражаются после сохранения:

In [1]: %load_ext autoreload

In [2]: %autoreload 2

In [3]: Import MODULE

In [4]: my_class = Module.class()
        my_class.printham()
Out[4]: ham

In [5]: #make changes to printham and save
In [6]: my_class.printham() 
Out[6]: hamlet
3 голосов
/ 20 сентября 2011

Я использовал следующее при импорте всех объектов из модуля, чтобы убедиться, что web2py использовал мой текущий код:

import buttons
import table
reload(buttons)
reload(table)
from buttons import *
from table import *
1 голос
/ 04 октября 2009

Я не совсем уверен, что вы это имеете в виду, так что не стесняйтесь меня поправлять. Вы импортируете модуль - давайте назовем его mymodule.py - в вашей программе, но когда вы меняете его содержимое, вы не видите разницы?

Python не будет искать изменения в mymodule.py при каждом его использовании, он загрузит его в первый раз, скомпилирует в байт-код и сохранит его внутри. Обычно он также сохраняет скомпилированный байт-код (mymodule.pyc). В следующий раз, когда вы запустите свою программу, она проверит, является ли mymodule.py более поздней версией, чем mymodule.pyc, и перекомпилирует ее при необходимости.

Если вам нужно, вы можете явно перезагрузить модуль:

import mymodule

[... some code ...]

if userAskedForRefresh:
    reload(mymodule)

Конечно, это сложнее, и у вас могут быть побочные эффекты в зависимости от того, что вы делаете со своей программой в отношении другого модуля, например, если переменные зависят от классов, определенных в mymodule.

В качестве альтернативы, вы можете использовать функцию execfile (или exec(), eval(), compile())

0 голосов
/ 02 октября 2018

Случаи будут разными для разных версий python. Ниже приведен пример версии Python 3.4 или выше:

hello import hello_world
#Calls hello_world function
hello_world()
HI !!
#Now changes are done and reload option is needed
import importlib
importlib.reload(hello)
hello_world()
How are you?

Для более ранних версий Python, таких как 2.x, используйте встроенную функцию перезагрузки, как указано выше. Лучше использовать ipython3, поскольку он обеспечивает функцию автозагрузки.

0 голосов
/ 04 декабря 2014

У меня возникла та же проблема при создании скрипта геообработки для ArcGIS 10.2. У меня был скрипт набора инструментов Python, сценарий инструмента и затем общий сценарий. У меня есть параметр для Dev / Test / Prod в инструменте, который будет контролировать, какая версия кода была запущена. Dev запускает код в папке dev, тестирует из тестовой папки и prod из папки prod. Изменения в общем сценарии разработки не будут выполняться при запуске инструмента из ArcCatalog. Закрытие ArcCatalog не имело значения. Даже если я выбрал Dev или Test, он всегда будет запускаться из папки prod.

Добавление перезагрузки (myCommonModule) в скрипт инструмента решило эту проблему.

...