当前位置: 首页 > 后端技术 > Python

你真的知道如何使用Python模块和工具包吗?

时间:2023-03-26 17:01:22 Python

在开发过程中,我们不能把所有的代码和资源放在同一个文件中。因此,模块导入在编码中非常常见。不管是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"",line1,inAttributeError:module'math'hasnoattribute'pi'>>>math因此,为了避免这个问题,请注意自己开发代码的命名文件。创建和安装本地工具包在Python开发过程中,经常使用pip从PyPI仓库安装工具包,可以在全局工程项目中使用。除了从仓库下载安装工具包,也可以在本地创建工具包并完成安装。创建本地安装包只需要创建setup.cfg和setup.py两个工程:#setup.cfg[metadata]name=local_structureversion=0.1.0[options]packages=structure#setup.pyimportsetuptoolssetuptools.setup()这里的版本名和版本号是可选的。然后,您可以执行以下命令将创建的安装包安装到本地:$python-mpipinstall-e。导入风格为了保持代码的可读性和可维护性,PEP8提出了模块导入的一些规则:将导入放在文件的顶部每行单独导入组导入:首先是标准库导入,然后是第三方导入,最后是原生applicationorlibraryimports在每个组内按字母顺序排列Imports绝对导入优先相对导入避免使用通配符导入frommoduleimport*#StandardlibraryimportsimportsysfromtypingimportDict,List#Thirdpartyimportsimportfeedparserimporthtml2text#ReaderimportsfromreaderimportURLresourceimport另外对于modules和toolkits,代码开发时经常会用到外部资源包,对于外部资源包的导入,可以使用importlib.resources。它是Python3.7中的标准模块。使用它有两个好处:它使导入方法更加一致,并且可以更轻松地访问其他包中的资源文件。例如>>>fromimportlibimportresources>>>withresources.open_text("books","alice_in_wonderland.txt")asfid:...alice=fid.readlines()动态导入Python是一种动态语言,它是其主要特点之一。动态语言允许你在程序运行时做很多事情,你可以添加属性,重新定义方法,更改模块的文档字符串。例如,通过修改print()函数使其不执行任何操作:>>>print("Hellodynamicworld!")Hellodynamicworld!>>>#重新定义内置的print()>>>print=lambda*args,**kwargs:None>>>print("Hush,everybody!")>>>#没有打印在上面的例子中,打印函数由匿名函数重新定义。除了这种方法,还有一种更容易使用的动态导入方法,就是使用importlib。让我们从一个例子开始,#docreader.pyimportimportlibmodule_name=input("Nameofmodule?")module=importlib.import_module(module_name)print(module.__doc__)import_module()返回一个可以绑定到任何变量的模块对象。然后您可以将该变量视为常规导入模块。$pythondoccreader.py模块名称?math这个模块总是可用的。它提供对C标准定义的数学函数的访问。$pythondoccreader.py模块名称?csvCSV解析和写入。在每种情况下,模块都通过import_module()访问以进行动态导入。循环导入循环导入发生在两个或多个模块相互导入时。例如,有两个模块yin.py和yang.py:yinprint(f"Goodbyefromyang")当试图在交互式命令行下导入yin时,会发生以下情况:>>>importyinHellofromyinHellofromyangGoodbyefromyangGoodbyefromyin有些同学会很困惑,所以互相导入,won这是一个无限循环吗?这是由于Python的模块缓存机制。yin导入后先加入缓存,后面再导入,会先引用缓存区,避免死循环。以上就是本次分享的全部内容。觉得文章还不错的话,请关注公众号:Python编程学习圈,每日干货分享,发送“J”还能收到海量学习资料,涵盖Python电子书和教程,数据库编程、Django、爬虫、云计算等。或者去编程学习网了解更多编程技术知识。