Python中的模块、包、库的区别

您所在的位置:网站首页 什么是opengles31扩展包 Python中的模块、包、库的区别

Python中的模块、包、库的区别

2024-07-11 03:09| 来源: 网络整理| 查看: 265

此为学习笔记的整理与记录,方便个人查阅、回顾、复习

文章目录 一、模块(一)什么是模块?(二)模块的导入(三)if __name __ == ' __main __':(四)模块的路径 二、 包(一)什么是包?(二)包的导入 三、 库附一、模块导入示例二、__init __.py模块 参考

一、模块 (一)什么是模块?

  就是扩展名为.py的文件,里面定义了一些函数和变量。   通过使用模块,不仅可以有效地避免命名空间的冲突,还可以将一个较大的程序分为多个文件,提升代码的可维护性和可重用性。

(二)模块的导入

  【点击查看模块导入示例】

import 模块名 [as 别名1], 模块名2 [as 别名2],…from 模块名 import 成员名1 [as 别名1],成员名2 [as 别名2],…

  其中,用 [] 括起来的部分,可以使用,也可以省略。

  注意!尽量不要使用from demo import *的方式进行导入,否则很容易出现名称重复的情况。   例如,如果有两个模块里面有相同的成员,或者你自己定义了某一个对象和demo module里面的成员(例如函数)重名了,运行的时候会出问题。因为此时我们无法确认,我们所指的是自己定义的对象还是demo module里面的成员。

(三)if __name __ == ’ __main __':

  在完成一个模块的编写之前,我们一般会对模块中的功能进行测试,看看各项功能是否正常运行。对于这些测试的代码,我们希望只在直接运行这个py文件的时候执行,在用其他的程序import这个模块的时候不要执行。这个时候就要借助Python内置的__name__变量。

当一个py文件被直接运行的时候,__ name__变量的值为__main__。当一个py文件被import到其他程序的时候,这个py文件里面的__name__变量的值为这个py文件的名字。

  利用__name__变量的这个特点,结合一个if语句,让我们import某一个模块的时候只用到它提供的功能,而不要运行里面用来测试的代码

(四)模块的路径

  对于用import语句导入的模块,Python会按照下面的路径列表顺序地查找我们需要的模块:

当前的工作目录PYTHONPATH(环境变量)中的每一个目录Python 默认的安装目录

  如果我们写的模块没有放在上述三类路径,那么在导入时,Python解释器提示找不到这个模块 ModuleNotFoundError: No module named ‘模块名’。

▲解决方法

▲ 向sys.path变量中临时添加模块文件所在的完整路径

import sys sys.path.append(r'D:\xxx\yyy')

▲ 将模块移动到sys.path 变量中已包含的路径中 ▲ 修改path 系统的环境变量

  其中,环境变量又分为用户变量(仅对当前用户生效)和系统变量(对系统里所有用户均生效)。Python在使用path变量时,会先按照系统path变量找,然后按照用户path变量的路径找。通常情况下,设置用户path变量即可

二、 包 (一)什么是包?

  在模块之上的概念,为了方便管理而将文件进行打包。包目录下第一个文件必须是__init__.py,否则就是普通股的文件夹目录。然后就是一些模块文件和子目录,假如子目录中也有__init__.py,那么它就是这个包的子包了。如下图目录结构所示:

package |- __init__.py |- subpackage1 |- __init__.py |- a.py |- subpackage2 |- __init__.py |- b.py |- c.py

Python包具有3个性质

它实质上是一个文件夹该文件夹里面一定有__ init__.py模块,其他的模块可以有也可以没有它的本质依然是模块,因此一个包里面还可以装其他的包 (二)包的导入

  导入包的方法和导入模块比较类似,只不过由于层级比一般模块多了一级,所以多了一条导入形式。

import 包名[.模块名 [as 别名]]from 包名 import 模块名 [as 别名]from 包名.模块名 import 成员名 [as 别名]

  其中,用 [] 括起来的部分,可以使用,也可以省略。我们在导入包的时候,实际上是导入了它的__init__.py文件。

三、 库

  具有相关功能模块、包的集合。这也是python的一大特色之一,即具有强大的标准库、第三方库以及自定义模块。

标准库:下载安装的python里那些自带的模块。第三方库:就是由第三方机构发布的,具有特定功能的模块。自定义模块:自己编写使用的模块。 附 一、模块导入示例 |-main.py |-arithmetic |-add.py |-sub.py |-mul.py |-mul.py

  文件目录结构如上。其中,main.py是程序入口,用不同的方式来import四则运算的各个子模块,arithmetic模块实现四则运算。   每个文件的代码如下:

# # @file main.py # import arithmetic.add import arithmetic.sub as sub from arithmetic.mul import mul from arithmetic import dev def letscook(x, y, oper): r = 0 if oper == "+": r = arithmetic.add.add(x, y) elif oper == "-": r = sub.sub(x, y) elif oper == "*": r = mul(x, y) else: r = dev.dev(x, y) print("{} {} {} = {}".format(x, oper, y, r)) ----------------------------------------------------------------- # # @file add.py # def add(a, b): return a + b ----------------------------------------------------------------- # # @file sub.py # def sub(a, b): return a - b ----------------------------------------------------------------- # # @file mul.py # def mul(a, b): return a * b ----------------------------------------------------------------- # # @file dev.py # def dev(a, b): return a / b 二、__init __.py模块 性质 它本身是一个模块,可以是一个空文件这个模块的模块名不是__init__,而是这个包的名字,也就是装着__init__.py文件的文件夹的名字作用是将一个文件夹变为一个Python模块它可以不包含代码,不过一般会包含一些Python初始化代码(例如批量导入我们需要用到的模块,这样我们就不用在用到的时候再一一导入),在这个包被import的时候,这些代码会自动被执行【查看示例①】以from 包 import * 导入时,包内的模块是受__init__.py限制的。import会把在__init__.py文件中注册的包的子模块和子包导入到当前作用域中来,如果包中某个模块不在__init__.py文件中,会报错【查看示例②】 示例①

  如上述 模块导入示例, 为了使用arithmetic中的某个子模块(main.py中我们展示了四种不同的方式),必须使用非常繁琐地import语句;在使用的时候,也有可能需要使用非常繁琐的表达式;如果在不同的地方使用arithmetic的子模块,都需要写这么繁琐的import或者使用表达式这就是为什么需要利用__init__.py来简化使用。

添加__init__.py文件,文件目录结构如下

|-main.py |-arithmetic |-__init__.py |-add.py |-sub.py |-mul.py |-mul.py

在__init__.py中编写如下代码:

# # @file __init__.py # import arithmetic.add import arithmetic.sub import arithmetic.mul import arithmetic.dev add = arithmetic.add.add sub = arithmetic.sub.sub mul = arithmetic.mul.mul dev = arithmetic.dev.dev

同样,对main.py进行了一些适当的修改。

# # @file main.py # import arithmetic as a4 def letscook(x, y, oper): r = 0 if oper == "+": r = a4.add(x, y) elif oper == "-": r = a4.sub(x, y) elif oper == "*": r = a4.mul(x, y) else: r = a4.dev(x, y) print("{} {} {} = {}".format(x, oper, y, r)) x, y = 3, 8 letscook(x, y, "+") letscook(x, y, "-") letscook(x, y, "*") letscook(x, y, "/")

  在__init__.py中, import了arithmetic下的所有子模块,并在__init__.py中给各个子模块的核心功能取了新的名字,作为arithmetic模块的变量。所以在main.py中import了arithmetic模块之后,就可以直接进行使用了。如果使用from arithmetic import * 语句,那么就可以使用add、sub、mul、dev,连a4都省了。   另外,若模块中含有 __all__变量,以“from 模块名 import *”的形式导入该模块时,该文件中只能使用__all__ 列表中指定的成员。(注意!__all__ 变量仅限于在其它文件中以“from 模块名 import *”的方式引入,即__all__ 变量对“import 模块名”、 “from 模块名 import 对象成员”不起作用)

__ all__ 变量:该变量的值是一个列表,存储的是当前模块中一些成员(变量、函数或者类)的名称。

沿用上例,修改__ init__.py如下:

# # @file __init__.py # import arithmetic.add import arithmetic.sub import arithmetic.mul import arithmetic.dev add = arithmetic.add.add sub = arithmetic.sub.sub mul = arithmetic.mul.mul dev = arithmetic.dev.dev __all__ = ["add","sub","mul"]

修改main.py文件如下:

# # @file main.py # from arithmetic import * def letscook(x, y, oper): r = 0 if oper == "+": r = add(x, y) elif oper == "-": r = sub(x, y) elif oper == "*": r = mul(x, y) else: r = dev(x, y) print("{} {} {} = {}".format(x, oper, y, r)) x, y = 3, 8 letscook(x, y, "+") letscook(x, y, "-") letscook(x, y, "*") letscook(x, y, "/")

  运行main.py文件,执行结果如下:NameError: name ‘dev’ is not defined   注意:__ all__ 是模块中提供的变量,如同 __ name__,不仅可以在__ init__.py中运用,也可以在其他普通的模块中运用,因为__ init__.py本身就是一个模块。

示例②

文件目录结构如下

|-main.py |-arithmetic |-__init__.py |-add.py |-sub.py |-mul.py |-mul.py

在__init__.py中编写如下代码:

# # @file __init__.py # import arithmetic.add import arithmetic.sub import arithmetic.mul add = arithmetic.add.add sub = arithmetic.sub.sub mul = arithmetic.mul.mul

main.py文件如下:

# # @file main.py # from arithmetic import * def letscook(x, y, oper): r = 0 if oper == "+": r = add(x, y) elif oper == "-": r = sub(x, y) elif oper == "*": r = mul(x, y) else: r = arithmetic.dev.dev(x, y) print("{} {} {} = {}".format(x, oper, y, r)) x, y = 3, 8 letscook(x, y, "+") letscook(x, y, "-") letscook(x, y, "*") letscook(x, y, "/")

  在__init__.py中, import了arithmetic下的add、sub、mul子模块,并在__init__.py中给各个子模块的核心功能取了新的名字,作为arithmetic模块的变量。但是没有导入arithmetic的dev模块,因此使用此模块的dev函数时需要用完整路径 arithmetic.dev.dev 进行验证。运行main.py文件,执行结果如下:

3 + 8 = 11 3 - 8 = -5 3 * 8 = 24 Traceback (most recent call last): File "D:\main.py", line 21, in letscook(x, y, "/") File "D:\main.py", line 12, in letscook r = arithmetic.dev.dev(x, y) AttributeError: module 'arithmetic' has no attribute 'dev' __ init__.py的设计原则 不要污染现有的命名空间。模块一个目的,是为了避免命名冲突,如果你在种用__init__.py时违背这个原则,是反其道而为之,就没有必要使用模块了。利用__init__.py对外提供类型、变量和接口,对用户隐藏各个子模块的实现。一个模块的实现可能非常复杂,你需要用很多个文件,甚至很多子模块来实现,但用户可能只需要知道一个类型和接口。就像我们的arithmetic例子中,用户只需要知道四则运算有add、sub、mul、dev四个接口,却并不需要知道它们是怎么实现的,也不想去了解arithmetic中是如何组织各个子模块的。由于各个子模块的实现有可能非常复杂,而对外提供的类型和接口有可能非常的简单,我们就可以通过这个方式来对用户隐藏实现,同时提供非常方便的使用。只在__init__.py中导入有必要的内容,不要做没必要的运算。如示例①,import arithmetic语句会执行__ini__.py中的所有代码。如果我们在__init__.py中做太多事情,每次import都会有额外的运算,会造成没有必要的开销。 参考

知乎问答:python中的模块、库、包有什么区别 知乎问答:__ init__.py的神奇用法



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3