python导入模块和包

python导入模块

模块就是 Python 程序。换句话说,任何 Python 程序都可以作为模块

python导入模块的2种方式

import 导入模块的语法:

1.import 模块名1 [as 别名1], 模块名2 [as 别名2],…

使用这种语法格式的 import 语句,会导入指定模块中的所有成员(包括变量、函数、类等)。

不仅如此,当需要使用模块中的成员时,需用该模块名(或别名)作为前缀,否则 Python 解释器会报错。

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

使用这种语法格式的 import 语句,只会导入模块中指定的成员,而不是全部成员。同时,当程序中使用该成员时,无需附加任何前缀,直接使用成员名(或别名)即可。

import 模块名 as 别名

1
2
3
4
5
6
# 导入sys、os两个模块
import sys,os
# 使用模块名作为前缀来访问模块中的成员
print(sys.argv[0])
# os模块的sep变量代表平台上的路径分隔符
print(os.sep)

上面第 2 行代码一次导入了 sys 和 os 两个模块,因此程序要使用 sys、os 两个模块内的成员,只要分别使用 sys、os 模块名作为前缀即可

from 模块名 import 成员名 as 别名

下面程序使用了 from…import 最简单的语法来导入指定成员:

1
2
3
4
# 导入sys模块的argv成员
from sys import argv
# 使用导入成员的语法,直接使用成员名访问
print(argv[0])

第 2 行代码导入了 sys 模块中的 argv 成员,这样即可在程序中直接使用 argv 成员,无须使用任何前缀。

导入模块成员时,也可以为成员指定别名,例如如下程序:

1
2
3
4
# 导入sys模块的argv成员,并为其指定别名v
from sys import argv as v
# 使用导入成员(并指定别名)的语法,直接使用成员的别名访问
print(v[0])

第 2 行代码导入了 sys 模块中的 argv 成员,并为该成员指定别名 v,这样即可在程序中通过别名 v 使用 argv 成员,无须使用任何前缀。

Tips: 需要说明的是,一般不推荐使用“from 模块 import”这种语法导入指定模块内的所有成员,因为它存在潜在的风险。比如同时导入 module1 和 module2 内的所有成员,假如这两个模块内都有一个 foo() 函数,那么当在程序中执行如下代码时:

foo()

上面调用的这个 foo() 函数到底是 module1 模块中的还是 module2 模块中的?因此,这种导入指定模块内所有成员的用法是有风险的。

但如果换成如下两种导入方式:

import module1 import module2

接下来要分别调用这两个模块中的 foo() 函数就非常清晰。程序可使用如下代码:

1
2
3
4
#使用模块module1 的模块名作为前缀调用foo()函数
module1.foo()
#使用module2 的模块别名作为前缀调用foo()函数
module2.foo()

或者使用 from…import 语句也是可以的,但是得给别名

1
2
3
4
#导入module1 中的foo 成员,并指定其别名为foo1
from module1 import foo as fool
#导入module2 中的foo 成员,并指定其别名为foo2
from module2 import foo as foo2

此时通过别名将 module1 和 module2 两个模块中的 foo 函数很好地进行了区分,接下来分别调用两个模块中 foo() 函数就很清晰:

1
2
foo1() #调用module1 中的foo()函数
foo2() #调用module2 中的foo()函数

python导入包

实际开发中,一个大型的项目往往需要使用成百上千的Python模块,如果将这些模块都堆放在一起,势必不好管理。而且,使用模块可以有效避免变量名或函数名重名引发的冲突,但是如果模块名重复怎么办呢?因此,Python提出了包(Package)的概念。

简单理解,包就是文件夹,只不过在该文件夹下必须存在一个名为_init_.py的文件。

| 注意,这是 Python 2.x 的规定,而在 Python 3.x 中,init.py 对包来说,并不是必须的。

每个包的目录下都必须建立一个 _init_.py 的模块,可以是一个空模块,可以写一些初始化代码,其作用就是告诉 Python 要将该目录当成包来处理。

包是一个包含多个模块的文件夹,它的本质依然是模块,因此包中也可以包含包。例如,我们安装了 numpy 模块之后可以在 Lib\site-packages 安装目录下找到名为 numpy 的文件夹,它就是安装的 numpy 模块(其实就是一个包)

假如我们有如下文件结构的包:

1
2
3
4
my_package
┠── __init__.py
┠── module1.py
┗━━ module2.py

_init_.py

1
2
3
4
5
'''
http://c.biancheng.net/
创建第一个 Python 包
'''
print('http://c.biancheng.net/python/')

module1.py模块文件

1
2
3
#module1.py模块文件
def display(arc):
print(arc)

module2.py 模块文件

1
2
3
4
#module2.py 模块文件
class CLanguage:
def display(self):
print("http://c.biancheng.net/python/")

python导入包的3种方式

导入包的方法可归结为以下 3 种:

  1. import 包名[.模块名 [as 别名]]

  2. from 包名 import 模块名 [as 别名]

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

1) import 包名[.模块名 [as 别名]]

以前面创建好的 my_package 包为例,导入 module1 模块并使用该模块中成员可以使用如下代码:

1
2
import my_package.module1
my_package.module1.display("http://c.biancheng.net/java/")

运行结果为:

http://c.biancheng.net/java/

可以看到,通过此语法格式导入包中的指定模块后,在使用该模块中的成员(变量、函数、类)时,需添加“包名.模块名”为前缀。当然,如果使用 as 给包名.模块名”起一个别名的话,就使用直接使用这个别名作为前缀使用该模块中的方法。

另外,当直接导入指定包时,程序会自动执行该包所对应文件夹下的 init.py 文件中的代码,例如

1
2
import my_package
my_package.module1.display("http://c.biancheng.net/linux_tutorial/")

直接导入包名,并不会将包中所有模块全部导入到程序中,它的作用仅仅是导入并执行包下的 _init_.py 文件,因此,运行该程序,在执行 init.py 文件中代码的同时,还会抛出 AttributeError 异常(访问的对象不存在)

1
2
3
4
5
http://c.biancheng.net/python/
Traceback (most recent call last):
File "C:\Users\mengma\Desktop\demo.py", line 2, in <module>
my_package.module1.display("http://c.biancheng.net/linux_tutorial/")
AttributeError: module 'my_package' has no attribute 'module1'

2) from 包名 import 模块名 [as 别名]

仍以导入 my_package 包中的 module1 模块为例,使用此语法格式的实现代码如下:

1
2
from my_package import module1
module1.display("http://c.biancheng.net/golang/")

运行结果为:

1
2
http://c.biancheng.net/python/
http://c.biancheng.net/golang/

同样,既然包也是模块,那么这种语法格式自然也支持 from 包名 import * 这种写法,它和 import 包名 的作用一样,都只是将该包的 init.py 文件导入并执行。

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

此语法格式用于向程序中导入“包.模块”中的指定成员(变量、函数或类)。通过该方式导入的变量(函数、类),在使用时可以直接使用变量名(函数名、类名)调用,例如:

1
2
from my_package.module1 import display
display("http://c.biancheng.net/shell/")

运行结果为:

1
2
http://c.biancheng.net/python/
http://c.biancheng.net/shell/

Tips: Python __all__变量用法

事实上,当我们向文件导入某个模块时,导入的是该模块中那些名称不以下划线(单下划线“_”或者双下划线“__”)开头的变量、函数和类。因此,如果我们不想模块文件中的某个成员被引入到其它文件中使用,可以在其名称前添加下划线。

除此之外,还可以借助模块提供的 _all__变量,该变量的值是一个列表,存储的是当前模块中一些成员(变量、函数或者类)的名称。通过在模块文件中设置 _all 变量,当其它文件以“from 模块名 import *”的形式导入该模块时,该文件中只能使用_all_ 列表中指定的成员。

1
2
3
4
5
6
7
def say():
print("人生苦短,我学Python!")
def CLanguage():
print("C语言中文网:http://c.biancheng.net")
def disPython():
print("Python教程:http://c.biancheng.net/python")
__all__ = ["say","CLanguage"]

此时调用disPython() 函数会报错

再次声明,_all_ 变量仅限于在其它文件中以“from 模块名 import *”的方式引入。也就是说,如果使用以下 2 种方式引入模块,则 _all_ 变量的设置是无效的。

以“import 模块名”的形式导入模块

以“from 模块名 import 成员”的形式直接导入指定成员

参考链接:http://c.biancheng.net/python


觉得不错的话,给点打赏吧 ୧(๑•̀⌄•́๑)૭



wechat pay



alipay

python导入模块和包
http://yuting0907.github.io/2022/07/23/python导入模块和包/
作者
Echo Yu
发布于
2022年7月23日
许可协议