首页 > 编程问答 >ArcPro (3.2+) Python 脚本工具中从 .atbx Toolbox 相对导入本地模块

ArcPro (3.2+) Python 脚本工具中从 .atbx Toolbox 相对导入本地模块

时间:2024-08-07 03:35:31浏览次数:16  
标签:python arcgis arcpy

我设置了一个库和关联的 ArcGIS Toolbox,以便:

/root
├── Toolbox.atbx
├── mylib
│   └── my_function.py
├── my_tools
│   └── my_gp_script.py

我将代码存储库的开发克隆保存在公司共享服务器上的一个位置,并在 GitHub 上托管一份副本。当我进行更新时,我会同步共享版本,公司的其他人可以访问该版本来运行工具箱中提供的工具。因此,我需要这个结构是相对的和可移植的。

工具箱内的每个工具都嵌入了执行 my_tools 文件夹内的脚本工具的代码: exec(open('my_tools/my_gp_script.py').read()) 这些脚本然后通过 arcpy 编译和修改所需的参数,并且执行诸如 my_function.py 之类的函数。

这一切都运行良好,直到 ArcPro 3.2 更新(尽管从技术上讲我从 3.1 跳到了 3.3),其中从工具箱内执行 Python 脚本工具的方式发生了变化。| ||请参阅 ESRI 的参考(向下滚动到 Python 脚本工具,向下第二个响应):

https://community.esri.com/t5/python-documents/python-in-arcgis-pro-3- 2-faq/ta-p/1348851 其要点是:

在 3.1 中的值

是: 在执行期间: __file__ 在 3.2 中 C:\Path\MyToolbox.atbx#MyTool_MyToolbox.py

中的值是: 在执行期间: __file__ 在此更改之后,my_gp_tool.py 不再能够直接调用 C:\Path\MyToolbox.atbx\MyTool.tool\tool.script.execute.py

,因为它现在是从与源 Toolbox 不同的目录中执行的。 import mylib 我有一个临时解决方案我可以在每个脚本的开头添加

的地方,但这对我来说似乎有点臭。它还将该目录添加到整个 ArcPro 会话的 python 路径中,因为每次启动程序时都会加载一个 python 内核 - 这似乎可能会产生其他意想不到的效果。 sys.path.append(os.path.dirname(__file__.split(".atbx")[0])) 还有其他人处理过吗这个特定的更新问题?我应该重新配置根文件夹的布局方式吗?我更喜欢让工具箱的根目录相对干净,然后本质上是一个脚本文件夹(my_tools)和一个库文件夹(mylib),但也许这从一开始就是错误的。我真的不想让人们在他们的用户设置上安装我的库,因为这会让更新成为一场噩梦,并且需要人们克隆源库并进行一系列会分散用户注意力的设置。

Has anyone else dealt with this particular update issue? Should I reconfigure how I have my root folder laid out? I rather liked having the root be relatively clean with the toolbox, and then essentially a scripts folder (my_tools), and a library folder (mylib), but maybe this was wrong from the start. I don't really want to have folks install my library on their user settings since this would make updates a nightmare, and require people to clone the source library and do a bunch of set up that will detract users.


遇到的问题很常见,并且是由于 ArcGIS Pro 3.2 中 Python 脚本工具执行环境的变化导致的。当前的临时解决方案确实有效,但正如所指出的,它并非理想选择,并且可能会导致问题。

以下是一些可以采用的更强大的解决方案:

1. 使用相对路径导入

与其将库路径添加到 sys.path ,不如使用相对路径直接从脚本工具导入模块。 这可以通过修改 my_gp_script.py 来完成,如下所示:

import os
import sys

# 获取脚本目录的绝对路径
script_dir = os.path.dirname(os.path.abspath(__file__))

# 将库目录添加到 Python 路径
library_dir = os.path.join(script_dir, '..', 'mylib')
sys.path.insert(0, library_dir)

# 现在,可以导入所需的模块
import my_function

# 的脚本工具代码的其余部分
# ...

此方法确保脚本始终可以找到库,而不管工具箱的位置如何。

2. 将库打包为 Python 包

更强大的解决方案是将库打包为 Python 包。这使可以更轻松地分发和安装库,并避免与相对路径相关的任何问题。

为此,需要创建一个 setup.py 文件,并在库目录中创建一个 __init__.py 文件。以下是示例:

/root
├── Toolbox.atbx
├── mylib
│   └── __init__.py
│   └── my_function.py
├── my_tools
│   └── my_gp_script.py
└── setup.py

setup.py 文件的内容可能如下所示:

from setuptools import setup, find_packages

setup(
    name='mylib',
    version='0.1.0',
    packages=find_packages(),
)

创建包后,可以使用 pip 在本地或共享服务器上安装它:

pip install . -e 

安装后,可以像导入任何其他 Python 包一样从脚本工具导入库:

from mylib import my_function

3. 使用 ArcGIS Pro 项目包 (.arcpyproj)

如果希望将工具箱和库捆绑在一个可分发的包中,可以考虑创建一个 ArcGIS Pro 项目包 (.arcpyproj)。此包可以包含的工具箱、库和任何其他必需的文件或数据。然后,用户可以将包安装到其 ArcGIS Pro 实例中,并以这种方式访问这些工具和库。

建议:

  • 使用相对路径导入 是一个简单的解决方案,适用于较小的项目。
  • 将库打包为 Python 包 是更强大的解决方案,建议用于大型或复杂的库。
  • 使用 ArcGIS Pro 项目包 是在单个包中分发工具箱和库的便捷方法。

选择最佳解决方案取决于的特定需求和项目复杂性。

标签:python,arcgis,arcpy
From: 78840745

相关文章

  • Python vs. R:揭秘机器学习领域的双璧
    一、引言1.1背景介绍随着大数据和人工智能技术的飞速发展,机器学习已经成为了一个热门领域。在机器学习领域,Python和R是两种广泛使用的编程语言。Python因其简洁易读的语法和强大的库支持,成为了最受欢迎的编程语言之一。而R则以其强大的统计分析和数据可视化能力,在统计学......
  • Windows10 安装编译后的 pysqlcipher3-1.2.1 基于 Python 3.8.10
    Windows10安装编译后的pysqlcipher3-1.2.1基于Python3.8.10本文主要是将直接安装编译后的文件,不一定的成功,但是可以尝试使用,若无法直接安装,请参考编译过程,自行编译安装,编译过程见这里安装pysqlcipher3这里用32位举例因为64位安装完全相同,只需要把对应的位数换成64......
  • 【Python】Python基础语法知识点汇集
    Python是一种高级的、解释型的编程语言,以其清晰的语法和代码可读性而闻名。本篇文章将汇集Python编程的基础语法知识点,为初学者提供一个全面的学习指南。......
  • 启动Python 的内置服务器访问本地图片
    要使用Python的内置服务器访问本地图片并正确地显示在浏览器中,你需要将图片文件放在内置服务器的根目录或其子目录中。以下是详细步骤:1.将图片文件复制到服务器根目录:例如,将zheng.jpeg文件复制到一个特定的目录中(例如,你的项目目录)。假设你将图片文件复制到C:\Users\panda......
  • 17:Python数据类型练习题
    #1获取c1,c2相同的元素列表c1=[11,22,33]c2=[22,33,44]foriinc1:ifiinc2:print(i)#2获取c1中有,c2没有的元素列表foriinc1:ifinotinc2:print(i)#3获取c2中有,c1没有的元素列表foriinc2:ifinotinc1:print(i)#4获......
  • (Jmeter新玩法)Python 调 Jmeter执行参数化jmx脚本
    #Python调Jmeter执行参数化jmx脚本importosfromos.pathimportjoinimporttimeimportrefromstringimportTemplatejmeter_Home=r"F:\softtotal\xxx\bin\jmeter.bat"#jmx文件路径currpath=os.path.dirname(os.path.realpath(__file__))#要运行的jmx脚......
  • python爬虫预备知识三-多进程
    python实现多进程的方法:fork、multiprocessing模块创建多进程。os.fork方法os.fork方法只适合于unix/linux系统,不支持windows系统。fork方法调用一次会返回两次,原因在于操作系统将当前进程(父进程)复制出一份进程(子进程),这两个进程几乎完全相同,fork方法分别在父进程和子进程中......
  • PEP 8 – Python 代码风格指南中文版(七)
    编程建议(2) 定义异常时,应该从Exception类继承,而不是从BaseException类继承。直接从BaseException继承的异常通常是那些几乎不应该被捕获的异常。设计异常层次结构时,应该基于捕获异常的代码可能需要进行的区分,而不是基于异常被抛出的位置。目标是通过编程方式回答“出了......
  • Python-记录一次迭代求和
    importitertoolsdefget_result(hope,list_input):""":paramhope:#期望相加所得参数:paramlist_input:#所有数值:return:"""defgenerate_combination(items,length):forcombinationinitertools.co......
  • 如何使用 Python 进行数据可视化,比如绘制折线图?
    要使用Python进行数据可视化,可以使用matplotlib库来绘制折线图。以下是一个简单的示例代码:首先,确保已安装matplotlib库。可以使用以下命令安装:pipinstallmatplotlib在Python脚本中导入matplotlib库:importmatplotlib.pyplotasplt准备数据,以x和y坐标列表的形式存......