关于python导入模块和package的一些深度思考
背景
在python中有导入模块和导入package一说,这篇文章主要介绍导入模块和package的一些思考。
首先什么是模块?什么是package?
模块:用来从逻辑上组织python代码(变量,函数,类),本质上就是以.py结尾的python文件
package:本质上就是一个目录,但是必须带一个init.py的文件,它是用来从逻辑上组织模块的
import的本质是什么?
导入模块的本质:就是把python文件拿来解释一遍
导入包的本质:就是执行该package下的init.py文件、
深入思考
导入模块
如果我现在有一个这样的目录:
在bin文件目录下的hello.py内容是:
def hello():print('i am in bin dir')
在Day5文件目录下的hello.py内容是:
def hello():print('i am in Day5 dir')
在pythonFile文件目录下的hello.py内容是:
def hello():print('i am in pythonFile dir')
如果我现在在bin目录下的test.py下写入
import hello
hello.hello()
会出现的结果是什么呢?
大家很自然会想到是
i am in bin dir
是的确实是这样的。但是为什么呢?
这个需要提及到环境变量的问题,我们可以看看当前文件所处的环境变量到底里面有什么?
使用下面的语句:
import sys, os
print('--------')
for path in sys.path:print(path)
print('--------')
其中sys.path是所有环境变量的所构成的列表,我们将里面的内容分行打印。可以得到:
--------
D:\0 sty file\myCode\pythonFile\Day5\bin
D:\0 sty file\myCode\pythonFile
C:\ProgramData\Anaconda3\python36.zip
C:\ProgramData\Anaconda3\DLLs
C:\ProgramData\Anaconda3\lib
C:\ProgramData\Anaconda3
C:\ProgramData\Anaconda3\lib\site-packages
C:\ProgramData\Anaconda3\lib\site-packages\Babel-2.5.0-py3.6.egg
C:\ProgramData\Anaconda3\lib\site-packages\win32
C:\ProgramData\Anaconda3\lib\site-packages\win32\lib
C:\ProgramData\Anaconda3\lib\site-packages\Pythonwin
--------
这是我电脑里面的当前文件运行时候的环境变量。我们可以知道导入模块和package时候,我们的程序会从这个sys.path中从前到后寻找这些目录下有没有我们要找的模块,可以看见D:\0 sty file\myCode\pythonFile\Day5\bin是在第一个的所有我们直接导入hello模块。python找到的D:\0 sty file\myCode\pythonFile\Day5\bin里面的hello.py找到之后,就不找了,然后打印出来了。
导入的问题来了
现在问题来了,我现在就想要导入D:\0 sty file\myCode\pythonFile\Day5下面的hello,那我应该怎么办?
我们知道在python中我们可以找到当前文件所在目录的父目录,然后将他加入到运行环境时候的环境变量中去,注意是运行环境中的,因为在当前python文件运行结束后,这个环境变量就释放了。
我们可以了解如下语句:
import sys, os # 导入系统模块
print(os.path.abspath(__file__)) #打印当前文件所处的绝对路径
print(os.path.dirname(os.path.abspath(__file__))) #打印当前文件所处的目录
# 打印当前文件所处的目录的父目录
print( os.path.dirname(os.path.dirname(os.path.abspath(__file__))))# Outputs:
# D:\0 sty file\myCode\pythonFile\Day5\bin\test.py
# D:\0 sty file\myCode\pythonFile\Day5\bin
# D:\0 sty file\myCode\pythonFile\Day5
然后我们就可以在写下如下的代码:
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR) # 将BASE_DIR加入到系统环境变量
我们将当前文件所在目录的父目录加入到环境变量中去,然后我们在打印下sys.path得到:
--------
D:\0 sty file\myCode\pythonFile\Day5\bin
D:\0 sty file\myCode\pythonFile
C:\ProgramData\Anaconda3\python36.zip
C:\ProgramData\Anaconda3\DLLs
C:\ProgramData\Anaconda3\lib
C:\ProgramData\Anaconda3
C:\ProgramData\Anaconda3\lib\site-packages
C:\ProgramData\Anaconda3\lib\site-packages\Babel-2.5.0-py3.6.egg
C:\ProgramData\Anaconda3\lib\site-packages\win32
C:\ProgramData\Anaconda3\lib\site-packages\win32\lib
C:\ProgramData\Anaconda3\lib\site-packages\Pythonwin
D:\0 sty file\myCode\pythonFile\Day5
--------
我们可以看出D:\0 sty file\myCode\pythonFile\Day5加到了sys.path的最后一个,现在我们将之前的开头的写的
import hello
hello.hello()
一定要注释,一定要注释,一定要注释,因为如果不去掉的话,这个hello.hello()方法就已经存放在内存里面了,不管你后面如何去该环境变量,python会始终去找到内存中直接有的hello()方法。
我们将这行代码加到test.py的最后面,运行得到结果是:
i am in bin dir
这是为什么呢,原因还是那个sys.path中个路径顺序的问题,如果我们要让我们设置的BASE_DIR 中的模块首先导入我们就需要用列表中的insert()方法2而不是‘append()’的了,这就避免了再环境变量中已经有的路径有同名的模块。
我们改为:
sys.path.insert(0, BASE_DIR)
发现输出的结果就是
i am in Day5 dir
完整代码如下:
# import hello #使用添加环境变量后的模块一定要注释到
# hello.hello()import sys, os
print('--------')
for path in sys.path:print(path)
print('--------')BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
#sys.path.append(BASE_DIR)
sys.path.insert(0, BASE_DIR)print('--------')
for path in sys.path:print(path)
print('--------')import hello
hello.hello()
最后提一下:
如果我们要使用pythonFile下的hello中hello(),道理还是一样的,大家自己去实现吧。
导入package
导入package时候设置环境变量的问题和导入模块是一样的,就不赘述了,但是需要注意的一点是导入package后,package下的init.py里的内容是自动执行的。
如我在test_package下的init.py中写入
print('i am in test_package __init__')
当我们在
import test_package
后就自动执行了,这在我们管理很多文件时候,进行初始化的作用相当好用啊。
转载请注明出处:
CSDN:楼上小宇_home:http://blog.csdn.net/sty945
简书:楼上小宇:http://www.jianshu.com/u/1621b29625df
关于python导入模块和package的一些深度思考相关推荐
- python导入模块_Python导入
python导入模块 Python import statement is used to import modules that we want to use in our program. Pyt ...
- python导入模块有同名_Python:导入与函数同名的模块
背景:第一次在SE上提问.我在 Python方面还很陌生,而且在编程方面也不是很有经验.我已经四处寻找,但我没有找到这个问题的答案,我非常感谢你的帮助. 我的问题是:如何导入与函数同名的模块? 具体来 ...
- python导入模块的三种方法,例子: import numpy和from numpy import * (import matplotlib 和 from matplotlib import *)
python导入模块有如下几种写法:以matplotlib为例 (跟numpy是一样的) 1,import matplotlib #整个导入matplotlib 2 , from matplotlib ...
- python哪个关键字可以导入模块_关于python导入模块import与常见的模块详解
0.什么是python模块?干什么的用的? Java中如果使用abs()函数,则需要需要导入Math包,同样python也是封装的,因为python提供的函数太多,所以根据函数的功能将其封装在不同的m ...
- [转载] vscode python导入模块
参考链接: 用Python导入模块 先说一下吧,我是python小白刚学python没多久,刚好要跟着教程做个小项目需要使用外部模块 使用vscode导入模块时报错,折腾了一下会,找了各种解决方法不太 ...
- python模块导入教学_【python基础课|今日教学内容:Python导入模块的方式,学python的必备技能】- 环球网校...
[摘要]在这个科学技术高速发展的时代,越来越多的人都开始选择学习编程软件,那么首先被大家选择的编程软件就是python,也用在各行各业之中,并被大家所熟知,所以也有越来越多的python学习者关注py ...
- python中导入模块使用哪个关键字_关于python导入模块的关键字介绍
关于python导入模块的关键字介绍 发布时间:2020-04-17 10:13:26 来源:亿速云 阅读:101 作者:小新 今天小编给大家分享的是关于python导入模块的关键字介绍,很多人都不太 ...
- python中导入模块是用哪个关键字_关于python导入模块import与常见的模块详解
0.什么是python模块?干什么的用的? Java中如果使用abs()函数,则需要需要导入Math包,同样python也是封装的,因为python提供的函数太多,所以根据函数的功能将其封装在不同的m ...
- 【Python问题】Python 导入模块的三种方式ModuleNotFoundError: No module named ‘模块名‘
Python 导入模块的三种方式ModuleNotFoundError: No module named '模块名' 问题 一.Python解释器查找模块文件的过程. 二.解决方法 记录一下 大家可以 ...
最新文章
- Linux/Centos7系统管理之深入理解Linux文件系统与日志分析
- python3.8什么时候出来,【新版本来临!Python 官网宣布,正式发布Python3.8.0!】- 环球网校...
- Vue学习小案例--分页组件封装
- SAP UI5 BindingParser
- 数字图像处理(拓展)
- ARM中ROM,RAM,FLASH区别
- 14-磁盘管理-df,du命令,磁盘分区
- Android访问php webservice
- 你不是一个人在战斗!
- 4.添加监听,使地图随鼠标,键盘移动并改变大小
- 学习swift从青铜到王者之Swift控制语句04
- [源码和文档分享]基于汇编语言实现打字练习软件
- cad上样条曲线上的点太多了_CAD如何将样条曲线转换成多段线
- 推荐 五个单变量时间序列数据集
- Windows操作系统----事件日志----事件查看器
- 储备池计算(Reservoir Computing)综述
- 【量化选基】每年初买入近5年 收益率最高的10支基金会暴富吗?
- ffmpeg+h264_nvenc+vs2019配置编译
- 3D MAX脚本教程1
- FFmpeg —— 录制Windows桌面与麦克风,音视频同步(附源码)