flask 源码之旅(基础)—import与模块

文章目录

[隐藏]

  • 初识import
  • 模块
    • 模块是什么?
    • 为什么一定要有模块?
    • 怎么使用模块?
  • import做了什么?
    • 搜索模块路径
    • 把模块放进来
  • 尾声
初识import
正所谓一方有难,八方点赞。君子生非异也,善假于物也---词子曰  

讲个故事:

我们的小明同学,有天他发现自己需要一辆车。然后,他收拾行囊出发去云南西双版纳挖橡胶,准备先造个轮胎。这是C语言工程师.....  

再讲个故事:

我们的小码同学,有天他发现自己需要一辆车。然后,他就去4S店提了一辆车。这就是python工程师.....  

听完上面的故事,人民群众纷纷表示:

哈哈,当然有关系了,python之所以强大,就是因为它提供了丰富的各类模块,避免我们重复的造轮子。让我们花更少的时间,做更多的事情。大家要始终谨记信条:“人生苦短,我用python”。

flask作为一个优秀的python web框架,正是如此在践行我们的信条,打开flask的源码,排在前面的永远是各种import。

作为一名python小白,面对这一坨import,面对苍天,涕然泪下:“这里面一定隐藏了肮脏的py交易,不然纯洁的我怎么会看不透这一切”。

没错是这个样子的,这里面的确隐藏了一堆肮脏的py交易。正是通过这一坨坨import,flask才变得如此强大,下面就让本人,一名普通的python工作者,来为你解开黑幕。

模块

莎士比亚曾经说过:

一千个观众眼中有一千个哈姆雷特,一个python程序员就可以导入一千个模块  

模块是什么?

A module is a file containing Python definitions and statements.  

模块就是一个普通的.py结尾的文件,里面包含了你写的python语句,定义的python变量。

模块之于一个完整的python程序,就像车轮之于车,装逼之于我。

为什么一定要有模块?

小明有一个G的种子,小码作为他的好兄弟难道想看片还要去自己再找一遍吗?现在这世道,天道苍凉,世风日下,快播都被封了,多难找片啊!小明他忍心对这一切熟视无睹吗?

不…..小明不忍心,他会拍拍小码的肩膀,给他一个会意的眼神:“拿去用,U盘自己来拷”。

为什么要有模块? 正是因为这个世界存在了太多没有必要的重复性的劳动。

怎么使用模块?

思考这个问题之前,我们先思考一下,小码应该怎么给小明要片看?

两种方式:

  1. 小码可以把小明所有的珍藏都拿过来,想看那个看那个。
  2. 小码可以直接从小明那里拿到想看的片子。

现在我们再回过头看一下python,python提供了import关键字,专门用于让你要片的……啊呸,是导入模块的。

首先,你可以这么导:

import A  

没错,简单粗暴,想用到那个模块的内容,就直接把整个模块导入进来。

譬如你想使用模块A里的函数b,这个时候就可以:

A.b()  

再然后,你还可以这么导:

from A import b  

想用到模块里的什么具体内容,就从模块中把具体的内容导入即可。

b()  

想看武藤兰,就直接要武藤兰,想看苍井空,就明白的要苍井空。如果你既想要苍井空,又想要武藤兰:

from A import a, b  

现在问题又来了,小码的电脑里已经有了一部苍老师了,这是从小刚那边又拷贝进来一部苍老师,文件名冲突了怎么办?

会用电脑的都知道,右键重命名文件,避免文件名冲突不就行了~

python 在导入模块时也提供了重命名的机制,它也要是为了避免命名冲突的。

于是你可以:

import A as B  

还可以:

from A import a as b  
import做了什么?

上面我们已经了解到了,import的作用就是导入模块。那么它具体做了什么?

和这个问题有异曲同工之妙的问题就是:怎么把大象放进冰箱里?

把大象放进冰箱里:

第一步,打开冰箱门。  第二步,把大象放进去。  

把模块导入进来:

第一步,找到模块。  第二步,把模块放进来。  

搜索模块路径

想要找到模块小可爱,第一个要去找的地方就是内建模块。

内建模块,顾名思义就是python语言的内置模块,典型的如os模块,sys模块。

内建模块在linux系统中,通常存放于/usr/lib64/python2.7/。

内建模块里没有的找到,就会去sys.path中找,sys.path再找不到,那就是真的找不到了。

有些会python的童鞋忍住不要问了,在内建模块里没找到,不应该去python进程执行路径或者环境变量$PYTHONPATH中搜寻吗?怎么到你这,就成了去sys.path中搜寻了?

其实在解释器启动时,它会把上面的两个路径加入到sys.path中的。

当前解释器被启动的路径:/root

将解释器启动路径切换到:/root/test

再设置一下环境变量:export PYTHONPATH=$PYTHONPATH:/root/test2

python解释器在启动时,除了会把python进程执行路径或者环境变量$PYTHONPATH导入到sys.path中外,还会依照一些规则导入一些其他路径到sys.path中。

所以总结一下:

如果你想导入一个模块,却告诉你ImportError找不到模块。这个时候你就要打印一下你的sys.path,检视一下模块的路径是否在你的sys.path中。

把模块放进来

前面有提到过,什么是模块?模块说白了也是一个普通的py文件而已。

顺便提一下,py文件只是一个普通的文本文件而已,不知道什么是文本文件的童鞋,你现在看到的就是文本文件。

python解释器想真正执行起来py文件,需要把这个py文件转换为字节码。什么是字节码?就是python解释器能够看懂进而按照它去执行的东西。就像老外对你说英语,你大脑里会有一个把英文转换为中文释义的过程,然后你才能明白老外是在讲嘛~

import导入模块时,它会找到这个模块的代码文本,把它转换成字节码,然后从头到位执行一遍这个模块。

我们可以自行测试一下:

1.建一个test.py文件,在里面加入以下代码:

print "hehe"  

2.打开python解释器,导入test模块,我们可以看到”hehe”被执行输出了

import导入模块的本质,就是把整个模块执行一遍,生成一个python模块对象。import test则是用test这个变量去引用模块对象。(ps:此处看不懂无所谓,后面会讲到的)。

另外,需要注意的是,import导入模块对象,只会在第一次import才会真正执行上面讲的导入流程,重复import并不会重复导入模块。

可以看到”hehe”只被输出了一次。

原因是在执行import后,python会把导入的模块缓存在sys.modules中。

sys.modules中已经存在的模块,不会再执行模块导入流程。

聪明的童鞋,应该就可以想到在搜索模块路径小章节,我们有提到import导入模块时,首先会查看是否是内建模块。

其实那个描述也是不太准确的,解释器在启动时就会把内建模块都加载到sys.modules中。与其说查看被导入的模块是否是内建模块,不如说查看被导入的模块是否在sys.modules中更准确。

尾声

文章到了这里,暂时就可以告一段落了。有不明白的问题或者文章以外不明白的问题欢迎留言探讨。

原文出处:juejin -> https://juejin.im/post/5baa424d6fb9a05cfd27da60

本站所发布的一切资源仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。如果侵犯你的利益,请发送邮箱到 [email protected],我们会很快的为您处理。
超哥软件库 » flask 源码之旅(基础)—import与模块