在开发过程中,我们不能把所有的代码和资源放在同一个文件中。因此,模块导入在编码中非常常见。不管是C++、Java,还是Python,Go。不同的功能和不同的模块可以分开。使用时,可以通过import关键字在一个模块中使用另一个模块提供的能力,可以大大提高代码开发的效率。对于Python这种高度依赖模块和工具包的编程语言来说尤其如此。Python中最常见的moduleimport被很多人不屑一顾,但是你真的了解Python中的import吗?我可以断言,绝大多数Python开发人员只是使用而不知道为什么。在这篇文章中,我们将详细而透彻地介绍Python模块导入的使用。模块和工具包模块和工具包(包)首当其冲的就是这两个概念,Python开发者经常混淆这两个概念。尽管两者之间有许多相似之处,但仍存在一些差异。因此,要想吃透import,首先需要了解modules和toolkit的异同点。ModulePython官网对模块的定义是这样的:一个模块有一个包含任意Python对象的命名空间,通常用作组织Python代码的对象。实际上,一个模块通常对应一个.py文件。该模块真正的作用是可以导入到其他代码中复用,例如:>>>importmath>>>math.pi3.141592653589793第一行代码,通过import将math模块导入到代码中,并通过math.pi调用pi属性。这里需要注意的是,这里写的math.pi不仅仅是一个简单的pi,而是将math作为所有属性的统一命名空间。命名空间对于保持代码的可读性和组织性非常有用。可以使用dir查看命名空间的内容:>>>importmath>>>dir()['__annotations__','__builtins__',...,'math']>>>dir(math)['__doc__',...,'nan','pi','pow',...]除了上面的直接导入,我们还可以导入模块下的特定部分:>>>frommathimportpi>>>pi3.141592653589793>>>math.piNameError:name'math'isnotdefined请注意,与之前的方法相比有一些变化。这里的pi是放在全局命名空间,而不是math命名空间。同样,先看Python官网对工具包的定义:一个Python模块,可以包含子模块,也可以递归包含子包。从技术上讲,包是具有__path__属性的Python模块。根据定义,包仍然是模块。但是,它们仍然存在某些差异。在编码方面,Python包需要在目录中创建一个名为__init__.py的文件。导入模块时,通常不会导入子模块和分包,但可以通过添加__init__.py来包含需要导入的子模块和分包。绝对导入和相对导入from...import...这种导入在当时的代码中经常遇到。如果我们有以下项目:world/│├──africa/│├──__init__.py│└───zimbabwe.py│├──europe/│├──__init__.py│├──greece.py│├──norway.py│└──spain.py│└──__init__.py想导入africa时可以这样:fromworldimportafrica也可以这样:from.importafrica那么这里的点(.)是什么意思呢?这里的点(.)是相对导入,可以理解为从当前包中导入africa。相反,在绝对导入语句中,需要显式命名当前包:fromworldimportafrica在编码过程中,可以选择绝对导入或相对导入。但是,在PEP8风格指南中,建议使用绝对导入。Python导入路径这是一个需要理解的问题。很多开发者从接触Python开始就用过PyCharm。它已经默认配置了导入路径。因此,开发者很难遇到无法导入的问题。但是,切换到VSCode和Sublime等需要更多自配置开发工具后,你会发现无法导入,或者导入工具包导致调用错误的问题。Python如何找到它导入的模块和包?可以尝试输出sys.path,你会发现输出列表主要包括以下三部分:当前脚本目录PYTHON_PATH环境变量和其他安装相关的目录正常情况下,Python会从头开始遍历列表,从Look开始对于每个位置的给定模块,直到第一个匹配。由于脚本所在的目录总是排在列表的第一位,所以在导入模块时会先从当前目录开始查找。因此,请确保不要将代码文件的名称与工具包的名称重复。例如,当前目录有一个名为math.py的文件:#math.pydefdouble(number):return2*number此时,您的导入按预期工作:>>>importmath>>>math.double(3.14)6.28不过,它已经涵盖了Python自带的数学标准库。如果我们误认为导入了标准的math模块,调用pi、sqrt等方法,就会报错:>>>math.piTraceback(mostrecentcalllast):File"
