Python中的import语句是导入一个文件,这条语句主要做三件事:

1 通过一定的方式,搜寻要导入的文件;

2 如果需要,就编译这个文件;

3 运行这个文件

但是,需要注意的是,所有这三个步骤,都只是文件再第一次导入的时候才会执行,如果文件已经导入了,后续的import会直接从内存里面找到已经加载的模块使用,换句话说,此时,import不会执行上面的3个步骤。

搜寻文件

在上面3个步骤中,最重要的就是搜寻要导入的文件。搜寻的的路径由5部分组成:

1 程序的Home目录

程序的Home目录根据运行程序的方式而不同。如果你是使用python python_program.py的方式来运行,那么,程序的Home目录就是python_program.py所在的目录;如果你是进入了python的可交互式命令行,那么程序的Home目录就是你启动可交互式命令行时,所在的目录。但是,如果你的*.py文件存在Home目录的子目录下面,那么,Python是不会自动搜寻子目录的。

2 PYTHONPATH环境变量

环境变量PYTHONPATH可以指定Python要搜索的目录,如果要设置,最好在前面加上export,即export PYTHONPATH=指定的目录

3 标准库目录

Python会自动搜寻标准库目录

4 .pth文件指定的目录

Python可以识别一个.pth文件,这个文件中每行指定一个搜寻目录。根据系统的不同,这个文件需要放置的位置也不一样。例如,如果你的系统是Windows的,那么这个文件可能需要放在Python的安装目录下,或者安装目录下的Lib/site-packages下面;如果你的系统是Unix-like的,那么,这个文件可能要放在/usr/local/lib/python3.3/site-packages或者/usr/local/lib/site-python下面。具体情况,需要参考Python的library document。

5 第三方扩展的Lib/site-package目录

Python会将第三方扩展库安装在这个目录下面,使它成为搜索路径的一部分。

上面提到的搜索路径方式,只是一个通用的方案,具体实现细节还要看各自的Python实现。要查看自己Python的搜索路径,可以使用sys module,通过sys.path就可以打印出自己Python实现的搜索路径,非常方便。

按需编译

Python并不是每一次导入文件,都会重新编译,Python编译的条件是:

1 Python源文件时戳比相应的字节码文件新,那么就重新编译;

2 对于<Python 3.2的版本来说,如果当前的Python实现和字节码中的"magic number"包含的版本号不一样,就会重新编译;对于>=Python 3.2之后的版本,如果字节码文件名中指定的版本号与当前Python实现不一样,也会重新编译

一旦编译导入成功,Python就会把字节码存入到内存中,通过sys.modules可以查看内存中存储的导入模块

import可以导入的类型

import可以导入的类型很多,包括:

.py源文件

.pyc字节码

.pyo 优化的字节码文件

文件目录

C/C++的动态库

C/C++的静态库

ZIP文件

内存镜像,比如Python的frozen package

Java class(Jython使用)

.NET(IronPython使用)

既然Python可以导入这么多文件,那么,如果在搜寻路径中同一个目录下,出现了b.py和b.pyc,那么,Python到底会使用哪一个文件呢?Python自己有一套选择标准,但是,这个标准可能随着Python实现的不同迭代版本而不同。

Python中的import语句的更多相关文章

  1. Python中from … import …语句

    from - import -语句可以让你从模块中导入一个指定的部分到当前模块

  2. 详解Python中的循环语句的用法

    一.简介 Python的条件和循环语句,决定了程序的控制流程,体现结构的多样性.须重要理解,if.while.for以及与它们相搭配的 else. elif.break.continue和pass语句 ...

  3. 一文了解Python中的判断语句

    判断(if)语句 目标 开发中的应用场景 if 语句体验 if 语句进阶 综合应用 01. 开发中的应用场景 生活中的判断几乎是无所不在的,我们每天都在做各种各样的选择,如果这样?如果那样?…… 程序 ...

  4. python中的import,reload,以及__import__

    python中的import,reload,以及__import__ 分类: UNIX/LINUX C/C++LINUX/UNIX shellpython2013-04-24 20:294536人阅读 ...

  5. Python中表达式和语句及for、while循环练习

    Python中表达式和语句及for.while循环练习 1)表达式 常用的表达式操作符: x + y, x - y x * y, x / y, x // y, x % y 逻辑运算: x or y, ...

  6. Python教程:Python中的for 语句

    Python 中的 for 语句与你在 C 或 Pascal 中可能用到的有所不同. Python教程 中的 for 语句并不总是对算术递增的数值进行迭代(如同 Pascal),或是给予用户定义迭代步 ...

  7. 归纳整理Python中的控制流语句的知识点

    归纳整理Python中的控制流语句的知识点 Python 解释器在其最简单的级别,以类似的方式操作,即从程序的顶端开始,然后一行一行地顺序执行程序语句.例如,清单 1 展示了几个简单的语句.当把它们键 ...

  8. Python中的基本语句

    本文简单的介绍下Python的几个基本语句. print语句 print可同时打印多个表达式,只要将他们用逗号隔开. >>> name='Gumy' >>> gre ...

  9. Python 模块化 from .. import 语句介绍 (二)

    from语句 例一. from pathlib import Path,PosixPath print(dir()) print(Path) print(PosixPath) 运行结果: ['Path ...

随机推荐

  1. 路由(二) router-link的使用

    main.js import Vue from 'vue'import App from './App'import VueRouter from 'vue-router'import footer ...

  2. jquery闭包概念

    //闭包:有参数的加载事件(空参数形式)(function($){ alert("123");})(jQuery); //有参数的加载事件(function($){ alert($ ...

  3. angular 打包

    ERROR in ng:///F:/IDEWorkspace/dsmc/dsmc-front-new/trunk/src/app/routes/city-manage/component-coding ...

  4. restframework中的那些参数你知道吗?

    序列化是很重要的过程, 在构建数据结构的时候, 往往会出现很多意想不到的问题, 有一些参数你要用, 但是没有办法穿过来, 怎么办> 今天这篇博客就是写我之前的一个小项目中用restframewo ...

  5. thinkphp5 部署到iis服务器url重写

    thinkphp部署到iis服务器配置url重写的解决方法: 1.下载 url rewrite.下载地址:https://www.iis.net/downloads/microsoft/url-rew ...

  6. day30 进程

    推荐两本书:现代操作系统和操作系统原来,学习好python以后再去研究.   并发:任务的切换,保存状态,存在io的是实现空间和时间的 重复利用 操作系统的发展历史: 第一代(1940-1955)手工 ...

  7. VMWare虚拟机的网络类型配置选择详解

    VMWare虚拟机网络有三种类型,当然还有最后一种类型就是“不使用网络连接”,哈哈....... VMWare在安装会有让选择网络类型的选项,如果不确认使用那一种网络类型,也可以先随便选择一种网络类型 ...

  8. BZOJ1001_狼抓兔子_KEY

    题目传送门 由题意得是最小割问题,又由最大流最小割定理可得只需要求无向图的最大流即可. 建双向边,跑Dinic,EK会超时. 注意在DFS时要加"if(!res)dist[now]=0;&q ...

  9. docker 在window 10 专业版的安装 && .net core 在docker的部署

    1.如果无法安装Hyper-V,八成是自己的杀毒软件给关了,我的是 电脑管家-启动项里面 给关掉了. 2.如果部署.net core 后 运行 报 An assembly specified in t ...

  10. FreeRTOS信号量的封装函数参数是二级指针

    1. 先看正确的封装方式,问题所在,为什么要用2级指针 void cissys_lockcreate(void** mutex) { //创建信号量,应该是互斥锁 *mutex = ((Semapho ...