【python语法】python import机制理解

1. 相关概念

1.1 import

import语句用来导入其他python文件(称为模块module),从而使用该模块里定义的类、方法或变量,从而达到代码复用的目的。

1.2 脚本 script

脚本通常是可以直接运行的代码,由其自身运行。

1.3 模块 module

通常,类、函数、变量存储在称成为模块(module)的.py文件中,可以隐藏代码实现的细节,将不同代码块重新组织,与主程序分离,简化主程序的逻辑,提高主程序的可读性;另外当需要更改具体细节代码时,只用更改模块代码,大量引用模块的主程序代码不用更改,方便程序更改优化。

script与module的重要区别:一个模块被当作模块导入时,文件名用作模块名,而如果将模块作为脚本执行,则模块名为 main
脚本或模块的名称可以使用__name__属性来获得;
在模块代码中可以使用 if name == "main"来使模块中的代码有不同行为:
当模块被导入时,其__name__ != “main”,使 if name == "main"中的代码不被执行;
当模块被当作脚本程序直接运行时,name == “main”,使 if name == "main"中代码被执行;

另外,当模块被导入时,若不加 if name == “main”,模块中除类,函数等代码会自动被运行。

模块的说明文档以注释的形式放在.py文件的开头,使用模块的__doc__属性访问说明文档,格式如下:

"""
模块说明文档
"""
print(xxx.__doc__)

1.4 包 package

包含模块文件和__init__.py文件的文件夹,可以理解为一组模块的容器。

python 3.3以后可以不包含__init__,py文件,但最好还是设置,init.py文件可以为空,用来标识所在文件夹是一个包;

__init__.py文件本身是一个模块,其名字不是__init__.py,而是所在包的名字;
__init__.py文件为空时 仅仅用 import Package 什么都做不了,在__init__.py文件可以放入一些python初始化代码,当包被 import 时,__init__.py文件中的代码被会自动执行:

  • 批量导入我们在此包中需要用到的模块,这样在使用时不用一一导入,方便实用

假如包名为Package1,包含Module1模块,Module1模块包含诸多类和函数,例如有class Add等等,
__init__.py文件也可以加上如下代码:
from Package1.Module1 import *
当另外程序用语句
import Package1 #导入包Package1后
可以在后边直接用:
add = Package1.Add()
导入包内模块中的类

  • 如使用 from Package import * 语句导入一个包的所有内容,需要在__init__.py文件加上:
    all = [Module1.py,Module2.py],其中包Package中有Module1和Module2文件

1.5 库 library

库是一个完整的文件系统,可以认为它是一个完整的项目打包,可直接调用或者运行,一个库可能包含多个包。

小结:

  • 数据封装在容器(list、tuple、dict、str)里
  • 代码封装在function里
  • function和data封装在class里
    以上三类都可以打包在module里
  • 多个module可以打包在package里
  • 多个package可以打包在library里

2. import机制

示例文件结构
便于解释说明,建立如下结构的文件系统:

Tree
|____m1.py
|____m2.py
|____Branch
	|____m3.py
	|____m4.py 

在m1.py写入:

import m2
from Branch import m3 
m2.printSelf()

在m2.py写入:

def printSelf():
	print("In m2")

在m3.py写入:

import m4

def printSelf():
	print("In m3")

在m4.py写入:
def printSelf():
print(“In m4”)

2.1 方式一

上述在m1中导入m2是最常用的绝对导入,即在import 后直接写模块名

绝对导入:
绝对导入时python会在两个地方查找目标包或模块

  • sys.path 列表中的路径,一般安装的python库的目录都在sys.path中,所以安装好的库可以直接import
  • 运行文件所在的目录(此处运行文件时m1,目录是…\Tree)

但是最好不要用上述方法导入同目录下的文件(包或模块,以下统称文件)

2.2 方式二

上述m1中导入m3也属于绝对导入(在python3):
from package_name import module_name

python 以绝对导入方式中的两种路径查找目标包,然后导入目标包中的目标模块。

运行上述m1.py会报错,m1用from package_name import module_name的方式绝对导入m3没问题,但m3也是用绝对导入的方式绝对导入m4会出问题,因为m4和m1不在同一目录,在运行文件m1的目录会找不到m4。

当把上述m4迁移到m1的同一级目录中,运行就没问题了,m3导入m4时在运行文件m1的目录中可以找到m4

可见以上导入方式都是绝对导入,只会在两中路径查找目标文件:

  • 针对sys.path路径,sys.path.append(“路径”),手动动态将目标文件的上一级路径加到sys.path肯定没问题
  • 针对当前运行文件所在目录,当前运行文件只有一个,也即程序运行的入口文件,上例中就是m1,而m3是非运行入口文件

2.3 方式三

相对导入
对于非运行入口文件m3导入m4可以使用相对导入

from . import m4
def printSelf():
	print("In m3")

# 此时运行是OK的

针对上边说的最好不要用import module_name 导入同目录下的文件问题,到这里就可以给出答案,因为类似m3导入m4这种情况,都是非运行入口文件,会出问题;
当用相对导入方式 from . import module_name就可忽略上述情况

  • from . import module_name:导入和自己同目录的文件
  • from .package_name import module_name:导入和自己同目录的包中的模块
  • from … import module_name:导入上级目录的文件
  • from …package_name import module_name:导入位于上级目录下的包的文件

2.4 方式四

上述运行入口文件m1导入m3用的绝对导入方式,也可以用相对导入

from .Branch import m3
m3.printSelf()

运行文件还可以使用命令行 -m 命令,用这种方式运行还会有其他import 导入问题,鉴于目前项目开发很少使用这种方式,因此有机会单独介绍。

总结

本文主要介绍了python中import语句的机制,主要分为绝对导入和相对导入。

参考:python中import的用法

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值