对Python中的import的理解(Python3.x)

本文转载链接:https://blog.csdn.net/qq_29051413/article/details/103499653
  结构化程式设计(英语:Structured programming),一种编程典范。它采用子程序、程式码区块(英语:block structures)、for循环以及while循环等结构,来取代传统的 goto。希望借此来改善计算机程序的明晰性、品质以及开发时间,并且避免写出面条式代码。
  在Python中,import的作用就是从其他地方载入当前源代码所需要的函数、类、对象等。

一、模块(module)和包(package)

  在Python中,模块是以".py"、".pyo"、".pyc"、".pyd"、".so"、".dll"结尾的文件形式来表示,对于新手而言,最常见的就是以”.py“结尾的模块文件。的形式是包含__init__.py文件的一个文件夹,文件夹中包含若干个模块。
  使用import的语法如下所示:

import module_name/package	# 导入一个模块或者包
import module_name1,module_name2	# 导入多个模块
from moudule_name import moudule_element [as new_name]	# 导入指定模块中的函数、属性、类等

  import寻找模块的搜索顺序为:首先判断这个module是不是built-in即内建模块,如果是则引入内建模块,如果不是则在一个称为sys.path的list中寻找。
  sys.path在python脚本执行时动态生成,包括以下3个部分:
  1、脚本执行的位置,即当前路径;
  2、环境变量中的PYTHONPATH, 即.bash_profilec;
  3、安装python时的依赖位置。

# main.py
import sys
sys.path

输出如下:
[’’, ‘/usr/local/lib/python37.zip’, ‘/usr/local/lib/python3.7’, ‘/usr/local/lib/python3.7/lib-dynload’, ‘/usr/local/lib/python3.7/site-packages’]
  可以看到sys.path输出的是一个list,第一个为空表示当前路径,后面的则表示相应的PYTHONPATH,这个输出是我的测试环境下的,不同平台环境有所出入。

二、import 的基本使用和细节

2.1 直接import导入模块

# 代码组织结构
-- demo
    |-- main.py
    |-- module01.py
	|-- module02.py

# module01.py
name = "module01-name"
def fun():
	print("It is module01-fun")

# module02.py
name = "module02-name"
def fun():
	print("It is module02-fun")

# main.py
import module01,module02
print(module01.name)
print(module01.name)
module01.fun()
module02.fun()

执行main.py后程序输出如下:
module01-name
module02-name
It is module01-fun
It is module02-fun

细节:当在py文件中import一个模块时,主要做了以下三件事:

  1. 为模块源代码文件中定义的对象创建一个命名空间,通过这个命名空间可以访问到模块中定义的函数及变量;
  2. 在新创建的命名空间里执行源代码文件;
  3. 创建一个名为源代码文件的对象,该对象引用模块的名字空间,这样就可以通过这个对象访问模块中的函数及变量;

2.2 使用from…import导入模块

# 代码组织结构
-- demo
    |-- main.py
    |-- module01.py
	|-- module02.py

# module01.py
name = "module01-name"
def fun():
	print("It is module01-fun")

# module02.py
name = "module02-name"
def fun():
	print("It is module02-fun")

# main.py
from module01 import name,fun
import module02
print(name)
print(module02.name)
fun()
module02.fun()

执行main.py后程序输出如下:
module01-name
module02-name
It is module01-fun
It is module02-fun

   细节:当直接使用import时,是建立了一个与模块文件名一样的对象来指向模块对应的命名空间。而使用from…import语句可以将模块中的对象直接导入到当前的命名空间.。也就是说,from…import语句不创建一个到模块命名空间的引用对象,而是把被导入模块的一个或多个对象直接放入当前的名字空间。同时执行一遍模块文件。(from可以理解成查找范围)
  使用from…import的一个隐患就是新导入的对象容易与当前命名空间存在的对象重名。当工程代码比较复杂时不建议直接使用from…import语句来导入,如果直接import会带来名称过长或引入频繁问题,可以使用from…import和as的结合。

2.3 从包中导入模块

# 代码组织结构
-- demo
    |-- main.py
    |-- pkg01
    	 |-- __init__.py
    	 |-- module01.py
		 |-- module02.py
	|-- pkg02
		 |-- __init__.py
    	 |-- module01.py
		 |-- module02.py

# __init__.py为空文件
# module0x.py
name = "pkg0x-module0x-name"
def fun():
	print("It is pkg0x-module0x-fun")

# main.py
import pkg01.module01,pkg01.module02
import pkg02.module01,pkg02.module02
print(pkg01.module01.name)
print(pkg01.module02.name)
print(pkg02.module01.name)
print(pkg02.module02.name)
pkg01.module01.fun()
pkg01.module02.fun()
pkg02.module01.fun()
pkg02.module02.fun()

执行main.py后输出如下:
pkg01-module01-name
pkg01-module02-name
pkg02-module01-name
pkg02-module02-name
It is pkg01-module01-fun
It is pkg01-module02-fun
It is pkg02-module01-fun
It is pkg02-module02-fun

  但是这种导入包方法太繁琐,特别是当一个包存在大量的模块和子包时,这种引用会显得名字过长。为了直接导入包名就可以使用包下面的所有模块,我们得修改__init__.py文件,根据上面的介绍知道,import一个模块会执行一遍模块。import一个包的本质就是import包里面的__init__.py文件,即__init__.py存在的第一个作用是表明当前文件夹是一个python包,当import一个包时会执行__init__.py文件,所以为了导入方便,我们在__init__.py文件中进行包模块的导入。改写如下:

# 代码组织结构
-- demo
    |-- main.py
    |-- pkg01
    	 |-- __init__.py
    	 |-- module01.py
		 |-- module02.py
	|-- pkg02
		 |-- __init__.py
    	 |-- module01.py
		 |-- module02.py

# __init__.py第一种改法
import pkg0x.module01,pkg0x.module02

# __init__.py第二种改法
from pkg0x import module01,module02

# __init__.py第三种改法
from . import module01,module02

# module0x.py (x=0,1)
name = "pkg0x-module0x-name"
def fun():
	print("It is pkg0x-module0x-fun")

# main.py
import pkg01,pkg02
print(pkg01.module01.name)
print(pkg01.module02.name)
print(pkg02.module01.name)
print(pkg02.module02.name)
pkg01.module01.fun()
pkg01.module02.fun()
pkg02.module01.fun()
pkg02.module02.fun()

执行main.py后输出如下:
pkg01-module01-name
pkg01-module02-name
pkg02-module01-name
pkg02-module02-name
It is pkg01-module01-fun
It is pkg01-module02-fun
It is pkg02-module01-fun
It is pkg02-module02-fun

2.4 使用from package import *

  当使用from package import *表明要把包的模块全部引入到当前命名空间,此时,只需要在__init__.py中写明要导入的函数、对象、类。举例如下:

# 代码组织结构
-- demo
    |-- main.py
    |-- pkg01
    	 |-- __init__.py
    	 |-- module01.py
		 |-- module02.py
	|-- pkg02
		 |-- __init__.py
    	 |-- module01.py
		 |-- module02.py

# pkg01/__init__.py
__all__ = [ 'module01', 'module02' ]

# pkg02/__init__.py
from . import module01,module02

# module0x.py (x=0,1)
name = "pkg0x-module0x-name"
def fun():
	print("It is pkg0x-module0x-fun")

# main.py
from pkg01 import *
import pkg02
print(module01.name)
print(module02.name)
print(pkg02.module01.name)
print(pkg02.module02.name)
module01.fun()
module02.fun()
pkg02.module01.fun()
pkg02.module02.fun()

执行main.py后输出如下:
pkg01-module01-name
pkg01-module02-name
pkg02-module01-name
pkg02-module02-name
It is pkg01-module01-fun
It is pkg01-module02-fun
It is pkg02-module01-fun
It is pkg02-module02-fun

三、总结

  import的作用是导入模块或者包,导入时会执行一遍模块文件(导入包则执行一遍__init__.py),导入的搜索路径为源代码所在路径、sys.path列表存储的路径以及系统依赖等相关环境。对包的导入时,包的__init__.py文件可什么都不写,当为了更方便导入包里面的模块时,需要在__init__.py中进行修改。
(有错误或补充的地方欢迎评论区进行评论,转载请注明来源。)

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值