在ArcGIS Python Toolbox中刷新导入的模块?


15

在ArcMap中使用python工具箱(.pyt)时,我通常会遵循以下模式:.pyt文件本身只是包装器,用于收集输入参数并定义工具本身。支持代码保存在单独的可单元测试模块中。

例:

import supporting_module

class MyTool(object):

    ...

    def execute(self, parameters, messages):
        """The source code of the tool."""
        some_input = parameters[0].valueAsText
        some_output = parameters[1].valueAsText

        supporting_module.do_something(some_input, some_output)
        arcpy.SetParameter(2, some_output)

这确实很好,但是在开发过程中遇到了一个令人沮丧的问题。在ArcMap中右键单击->刷新.pyt仅刷新.pyt文件的代码。它不会刷新导入的模块,因此,每当我在其中更改某些内容时,都必须关闭并重新打开ArcMap。幸运的是,由于我是独立测试代码,因此不必花很多时间,但这仍然是一个很大的麻烦。有没有办法解决?有点相关-有什么方法可以完全刷新Python控制台(我有一个自定义站点包,我还必须关闭/重新打开ArcMap才能从中引入更改)?

我正在使用ArcMap 10.2.1。

Answers:


14

我发现了这种可能性,/programming/1517038/python-refresh-reload

一个警告是,如果您有任何变量分配给模块,则将需要再次分配它们。

但是,如您在上面所写,您可以执行以下操作:

import supporting_module
def execute()
  reload(supporting_module)
  ...

这样,每次您运行该工具时,都将确保拥有更新的模块。一旦开发完成,就可以将其删除。


1
非常有用,这确实解决了我发布的简单示例。但是,如果supporting_module也导入其他帮助程序模块,则也需要使用reload来调用它们。我认为这是我们所能获得的最好的结果,因为它在Python加载模块的方式上是有意义的-如果第二天左右没有更强大的功能出现,我会将您的答案标记为答案。
Josh Werts 2014年

非常有帮助。我发现reload()在导入支持模块后立即在工具箱的PYT文件顶部调用即可。因此,如果工具箱包含多个工具,则不必在每个工具的execute()功能中重复进行重新加载。
迈克·芬奇

我不太了解这个答案如何解决问题。我将我的工具存储在.py文件中,并使用导入它们from pyfile import Tool,并添加了reload(tool)return typeError: reload() argument must be module。有任何想法吗?
拉特尼尔

2
我找到了解决方案!首先将py-File作为模块导入,重新加载,然后将其导入模块中。请参阅:stackoverflow.com/a/6946467/4139249
Ratnanil '18

5

这是一种比我之前建议的更不同且更可靠的方法。

我自己没有使用过此模块,但我认为它可以解决您的问题:

Python模块重新加载器

该库为Python实现了基于依赖项的模块重载器。与内置的reload()函数不同,此重新加载器将重新加载请求的模块和所有依赖于该模块的其他模块。

给定前面的示例,这将通过一次调用加载所有依赖关系:

import reloader
reloader.enable()

import supporting_module

def execute()
  reloader.reload(supporting_module)
  ...

这是我第一次注意到此模块,因此,如果您在工具中实施该模块,请评论一下它对您的效果如何。


好发现!如果完全按照您的显示进行添加,则此方法有效。如果.pyt文件本身发生更改,我只需要右键单击->在工具箱上刷新。支持模块及其子模块已成功重新加载。需要注意的是-我确实偶尔会遇到一些无法解释的异常,并导致ArcMap崩溃(尽管不幸的是,ArcMap崩溃确实不是那种异常)。注意-我仅使用支持模块和一个从属子模块对此进行了测试。将来可能会报告稳定性。
Josh Werts 2014年

1
超级,谢谢您的回复。是的,在驾驶ArcMap时,有时会感觉像是Crash Test Dummy。
cndnflyr 2014年

不幸的是,此重新加载程序遇到了太多的稳定性问题,因此我将所选答案更改为原始reload()内置函数。有时越简单越好!
2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.