参考《Python应该如何导入(import)模块及包》梳理
1. 整体概念基本介绍
虽然简简单单的导入import,其实涉及到很多的知识
我们导入往往是一个包,或者包内的一个模块,或者一个模块内的某些函数变量等
所以我们先对,包,模块,函数、变量做一个简单介绍
他们的包含关系是
包package(往往是一个目录/文件夹)》模块module(往往是一个文件)》变量,函数,类
直观来说,一个包往往包含多个模块文件或者一些子包,每个模块文件包含多个变量和函数方法,类等
下面分别是更详细的介绍
1.1 包package
通常包是一个目录
为了将目录视为包,必须在其内部包含一个名为 __init__.py
的文件。__init__.py
文件可以为空,也可以包含包的初始化代码。
1.2 模块 module
通常模块为一个文件,直接使用import来导入就好了。可以作为module的文件类
一个模块内往往包括多个变量,函数
当然实际上可以导入的四种包括
- 使用Python写的程序( .py文件)
- C或C++扩展(已编译为共享库或DLL文件)
- 包(包含多个模块)
- 内建模块(使用C编写并已链接到Python解释器内)
2 基本语法
这里涉及到名字空间的概念,具体可以看我前一篇博客Python进阶(一)名字空间 | 超详细名字空间解析 内置 全局 局部 调试查看-CSDN博客
名字空间简单理解就是一个变量和值的映射关系
2.1 import直接使用
import直接导入模块,会创建一个新的导入模块名字空间,当前文件会引用这个导入模块的名字空间
import module_name
2.2 from 及其用法
我们可以使用 from
关键字指定需要引入的具体内容:
使用from
语句可以将模块中的对象直接导入到当前的名字空间. from
语句不创建一个到模块名字空间的引用,而是把被导入模块的一个或多个对象直接放入当前的名字空间:
from module_name import function_name, class_name
from
语句支持逗号分割的对象,也可以使用星号*
代表模块中除下划线开头的所有对象(注意这里导入是不会导入单下划线开头的变量)
from socket import * # 载入所有对象到当前名字空间
如果一个模块如果定义有列表__all__
,则from module import * 语句只能导入__all__
列表中存在的对象。
# module: foo.py
__all__ = [ 'bar', 'spam' ] # 定义使用 `*` 可以导入的对象
3.1 as的用法
也可以使用 as
关键字给模块或内容起别名:
import module_name as alias
另外, as
也可以和 from
联合使用:
from socket import gethostname as hostname
h = hostname()
3 工作原理
3.1 搜寻
现在有一个问题,就是导入的时候解释器会去哪里搜寻模块?
当我们使用 import
语句时,Python 解释器会在一系列目录中搜索模块(sys.path列表)这些目录包括当前目录(包含运行脚本的目录)、内置模块目录、环境变量 PYTHONPATH
中指定的目录等。
一个典型的sys.path 列表的值:
Linux:
[’’, ‘/usr/local/lib/python2.0’,
‘/usr/local/lib/python2.0/plat-sunos5’,
‘/usr/local/lib/python2.0/lib-tk’,
‘/usr/local/lib/python2.0/lib-dynload’,
‘/usr/local/lib/python2.0/site-packages’]
Windows:
[’’, ‘C:\WINDOWS\system32\python24.zip’, ‘C:\Documents and Settings\weizhong’, ‘C:\Python24\DLLs’, ‘C:\Python24\lib’, ‘C:\Python24\lib\plat-win’, ‘C:\Python24\lib\lib-tk’, ‘C:\Python24\Lib\site-packages\pythonwin’, ‘C:\Python24’, ‘C:\Python24\lib\site-packages’, ‘C:\Python24\lib\site-packages\win32’, ‘C:\Python24\lib\site-packages\win32\lib’, ‘C:\Python24\lib\site-packages\wx-2.6-msw-unicode’]
空字符串 代表当前目录. 要加入新的搜索路径,只需要将这个路径加入到这个列表.
3.2 执行
假设某源代码文件初次引入某一个模块
执行的具体步骤如下
- 1.为源代码文件中定义的对象创建一个模块名字空间,通过这个名字空间可以访问到模块中定义的函数及变量。
- 2.在新创建的名字空间里完整执行模块文件和源代码文件。
- 3.创建一个名为源代码文件的对象,该对象引用模块的名字空间,这样就可以通过这个对象访问模块中的函数及变量,如:
import spam # 导入并运行模块 spam
print (spam.a) # 访问模块 spam 的属性
spam.foo()
c = spam.bar()
import
语句可以在程序的任何位置使用,你可以在程序中多次导入同一个模块,但模块中的代码 仅仅 在该模块被首次导入时执行。后面的import语句只是简单的创建一个到模块名字空间的引用而已。
这里我们注意到上面的第2点,一旦模块被导入,他的代码就会被执行一遍,但有些时候我不想让模块完整被执行,那么该怎么办呢?
3.3 避免导入模块代码执行
当一个模块被导入时,它的代码会被执行一次。如果你希望某些代码仅在模块被直接运行时而不是被导入时执行,可以使用 if __name__ == "__main__":
来进行条件判断。
if __name__ == "__main__":
# 这里的代码仅在模块被直接运行时执行
如下所示是一个详细的例子
假设我们有一个名为 example_module.py
的模块文件,内容如下:
# example_module.py
def add_numbers(a, b):
return a + b
# 如果模块被直接运行,则执行以下代码(比如直接运行python example_module.py)
if __name__ == "__main__":
x = 5
y = 10
result = add_numbers(x, y)
print(f"The sum of {x} and {y} is: {result}")
在这个例子中,example_module.py
定义了一个简单的函数 add_numbers
用于相加两个数字。然后,在模块的末尾,使用 if __name__ == "__main__":
来判断模块是被导入还是被直接运行。如果模块被直接运行(比如直接运行python example_module.py),就会执行一些特定的代码,例如计算两个数字的和并打印结果。
现在,如果我们在另一个脚本another_script.py中导入这个模块,if __name__ == "__main__":
之后的代码就不会被执行。例如:
# another_script.py
import example_module
result = example_module.add_numbers(8, 12)
print(f"The sum of 8 and 12 is: {result}")
会输出文章来源:https://www.toymoban.com/news/detail-806124.html
The sum of 8 and 12 is: 20
在这个例子中,虽然我们导入了 example_module
,但由于我们没有直接运行 example_module.py
,因此 if __name__ == "__main__":
之后的代码不会执行。只有当 example_module.py
被直接运行时,才会执行这部分代码。文章来源地址https://www.toymoban.com/news/detail-806124.html
到了这里,关于python进阶(二)导入import 机制 | 导入import 用法 工作原理全解析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!