在Python中import语句可以说是必不可少的语句,但往往用起来我总是分不清import那几种到底有什么区别,总结于此,以备查阅。

import

最简单的莫非import语句本身,例子有import cv2,这里的cv2既可以是环境变量目录中已经安装好的包,也可以是程序执行目录下的py文件或文件夹下的“__init__.py”文件,import的机制如下:

  • Python 中所有加载到内存的模块都放在 sys.modules 。当 import 一个模块时首先会在这个列表中查找是否已经加载了此模块,如果加载了则只是将模块的名字加入到正在调用 import 的模块的 Local 名字空间中。
  • 如果没有加载则从 sys.path 目录中按照模块名称查找模块文件,模块可以是py、pyc、pyd,找到后将模块载入内存,并加到 sys.modules 中,并将名称导入到当前的 Local 名字空间。

一个模块不会重复载入。多个不同的模块都可以用 import 引入同一个模块到自己的 Local 名字空间,其实背后的 PyModuleObject 对象只有一个。说一个容易忽略的问题:import 只能导入模块,不能导入模块中的对象(类、函数、变量等)。例如:模块 A(A.py)中有个函数 getName,另一个模块不能通过 import A.getName 将 getName导入到本模块,只能用 from A import getName。

需要注意的是:顺序嵌套时,比如A.py中import B,B.pyz中import C,但如果A中要用到C中的对象还是要重新import C,也就是import并没有顺序包含关系,同样由于一个模块并不会重复载入,所以这也不会导致资源的浪费。

import时还可以import文件夹下的模块,如import vision.yolov3,对包而言有import matplotlib.pyplot,特别地,如果引入的模块名字特别长(对,TensorFlow我就是说你),可以使用import tensorflow as tf,在随后代码中就可以用tf代替tensorflow了。

注意自己写模块时,import自己写的模块时可能只希望导入函数和类,而不希望执行其中的代码,这时需要用到一个条件判断语句:

if __name__ == '__main__'

当.py文件被直接运行时,if __name__ == '__main__'之下的代码块将被运行;当.py文件以模块形式被导入时,if __name__ == '__main__'之下的代码块不被运行。

from import

看看下面三行代码,你初看是不是感觉是一个意思:

import django.forms  # 1
from django import forms  # 2
from django.forms import *  # 3

在导入模块时,1、2几乎是等效的,只不过2不会执行代码。例如下面两行代码是等效的:

from matplotlib import pyplot as plt
import matplotlib.pyplot as plt

3就比较恐怖了,from A import * 将会导入A中所有的成员,包括变量,还是直接全局变量的那种。

故日常使用中尽量避免使用from A import *以避免不必要的麻烦,因为这样操作可能初看不会报错没有问题,殊不知某个变量早就不是你想的那样了……

使用import *就像一位贪婪的顾客到一家冰淇淋店,虽然他只想买一两勺子的冰淇淋,但是他却要求先品尝一下所有31种冰淇淋!

Last modification:January 26th, 2019 at 05:26 pm
If you think my article is useful to you, please feel free to appreciate