Follow Me: ArcPy(2)

本文结合《Programming ArcGIS 10.1 with Python Cookbook》一书,深入探讨ArcPy的使用,并揭秘Python令人困惑的Import系统,从DT_RPATH到LD_LIBRARY_PATH,再到类加载器的层次结构,揭示Python模块导入的全过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

木有想到隔了这么长时间才开始写这个系列的第二篇。2014年就这样过去了。在这段时间里,我在开篇中谈到的使用arcpy的项目已经上线,用户非常满意,邀请我们参加他们的board meeting,在会上狠狠的把我们表扬了一番。主席指着我们说:“你看,他们居然用XX万就作出了这么好的app!”。说实话,我怎么感觉他在骂我,还居然?也许是主席大人也意识到了这个问题,会后专程来和我攀谈,最后握着我的手说:“你放心,我们决定上二期。合同肯定还是你们的!由于funding cycle和fiscal year的原因,金额暂时无法确定,细节让我的小弟和你们老板谈。”听到这里,我觉得他其实可以再侮辱我一次。。。


这个项目中的arcpy完全是由小弟完成的。我只是在最开始时给了他一个用model builder生成的网络分析prototype。后来被他改的面目全非,性能奇差无比。最后不得不逐句打印每个arcpy调用的执行时间。还好,我们发现了原因:是线段截断这个本不该消耗太多时间的函数成了瓶颈!找了一个alternative后,性能大幅提升!至于为毛会这样,借用黄西在RTCA年会上的一句话:who care!木有办法啊,谁叫小笨懒呢!


貌似读者也发现了,其实俺还是没有能够有hands on的使用arcpy!那我们这个系列是不是就要说the end了呢?还好,我找到了一本讲arcpy的书《Programming ArcGIS 10.1 with Python Cookbook》。我决定就结合着这本书的结构和例子,用我自己的方式给大家来播讲这本书。所以首先对Eric Pimpler先生对这个系列提供素材表示感谢。


什么?我听见你在喊:“那是读书笔记而已!” 真的吗?你看了就知道了。Follow me and I won't fail you!


令人困惑的Python Import系统

在上一节中讲过了,arcpy是封装成一个Python的模块包的。因此在使用arcpy之前,必须从中引入相关的模块。以下是书中给出的第一个代码实例:

import arcpy.mapping as mapping
mxd = mapping.MapDocument("CURRENT")

小笨认为第一行import需要一些额外的解释。首先,请记牢: 如果import在最前面,import后面跟着的的只能是模块!(考试必背)

以上的import语句翻译成中文是:从arcpy这个包中中引入mapping模块,并用mapping作为arcpy.mapping模块的别名。正因为如此,在脚本中才可以直接使用mapping.MapDocument(),因为在这里的别名mapping会被替换为arcpy.mapping。这是一个对于Python import在2.0版本以后加入的一个扩充。喜欢打破沙锅问到底的同学请戳 这里(PEP221)

因此,如果你有如下的import方式(木有as,怎么听上去像木有菊花。。。),那在代码中引用mapping这个模块中的类型,变量时,必须使用模块的全名,那就是“arcpy.mapping“。

import arcpy.mapping
mxd = arcpy.mapping.MapDocument("CURRENT")

书中例子的等价写法可以是:

from arcpy import mapping
mxd = mapping.MapDocument("CURRENT")

这里你依然可以不使用模块的全名(木有包名)而直接引用其中的对象。一些python程序员推荐这种用法。下面会详细展开。

你可能会开始挖苦我了:“小笨,原来你是孔乙己啊!回字有几种写法啊?“

且慢,容我解释:之所以要在这里把import掰开揉碎的讲,是因为这是Python中一个非常tricky的地方。我更愿意叫它Python Import System。令人疑惑的是,直到Python 3.3以后,我们才能在官方文档中找到import的一整章节的系统介绍: The Import System

下面请允许我细细道来!请注意小笨会多次提及的两个问题:

1、变量/类型/函数是如何被引用的;

2、代码/库/模块是如何被加载的;

小笨要开始掉书袋了,如果你对程序语言考古不感兴趣,请忽略“******“分割线中的部分。




分割线开始**************************************分割线开始


以下凡是涉及操作系统的内容,若无说明,都默认为UNIX/Linux平台:

import这个概念,以小笨接触过的程序语言,最早可以追溯到C。C里面有include这个指示符,目的是引入头文件。我们知道在C这样一个强类型,静态语言中,使用变量和函数前都必须声明的。头文件的作用是提供一个类型定义,宏定义,函数声明的场所,以便多个C代码文件可以引用。从编译的过程来看,头文件的引入和展开是由预处理程序在编译开始前就完成的。顺便说一句,一个C程序的编译流程基本是:预处理-〉编译-〉优化-〉汇编生成-〉机器码生成-〉链接。不了解这个过程的同学请自行脑补!

如果你只是编译目标文件的话,引入头文件而不提供实现,编译器表示毫无压力。让子弹飞一会儿,反正那是链接器的工作。

如果我们试图生成一个可执行文件,而头文件对应的实现已经在二进制的程序库里,这个库的加载时机是由库的实现形式决定的。如果是一个静态库(可以理解为目标文件的合集),对应的目标文件会在编译时由链接器加入可执行文件中,作为可执行文件的一部分。如果这个静态库不在ld的查询路径上,链接器会报告“无法解析的引用”。被链接进可执行文件的静态库的目标文件存在于可执行文件的.text区;有关UNIX/Linux下可执行文件的结构, ELF (Executable and Linkable Format),请参考 wiki
<
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值