【python小课堂专栏】python小课堂15 - 史上最详细的包和模块import讲解篇

python小课堂15 - 史上最详细的包和模块import讲解篇

前言

在大量的代码设计中,我们不可能将所有代码都写在一个.py文件,所以有了包、模块,而为了代码可以重复利用(复用性),就有了类、函数的概念。类和函数在下次介绍。

python中的包

python中的包,对应到计算机中,可以理解为文件夹,但是文件加下必须有一个名为__init__.py的文件,若没有此文件,python则会认为其只是一个普通的文件夹。

打开pycharm,创建一个包,如下:
在这里插入图片描述

在这里插入图片描述

python中的模块

python中的模块就非常好理解了,实际上,之前所有的.py文件,我们都可以称之为一个模块。单独的一个py文件就是一个模块。

在这里插入图片描述

在这里插入图片描述

test1和test2不同区别就是test2是和package这个包是同级目录,而test1是属于package包的。

再来看下总的概念:

在这里插入图片描述

包和模块的引入

1.模块处于同级目录并且不在包下

当我们想在一个模块中使用另一个模块中的变量时,如何操作呢?test2、test3处于同一级目录。
在这里插入图片描述

我想在test3中引入test2的变量,test2.py中有个变量a = 2。
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

如上所示,只需要在当前模块,用import语句,即可导入模块,具体使用的时候需要用模块的名字.变量。

import 后面必须是模块的名称! ------> import modul name

还有一种写法如下图pycharm中:
在这里插入图片描述

如上所示,只需要在当前模块, from 模块名字 import 变量

2.模块处于同级目录在同一包下

来看下,test1,test4都属于package包下的模块。

在这里插入图片描述

test1.py中有着字符串a = ‘I am success!’
在这里插入图片描述

在test4.py中引用test1.py中的a,如何引用呢?

可以看到如下:
在这里插入图片描述

关键语法:import 包名.模块名 as 别名

但是!!!!!!!如果我们脱离pycharm,找到本机相应的python目录,通过cmd来运行下,看下效果如何:

在这里插入图片描述

在这里插入图片描述

可以清晰的看到上图,通过命令行模式执行就会报错!错误显示模块没有被找到:没有模块叫’package’。这是为什么呢?在pycharm中通过右键run as运行test4,可以看到控制台成功输出,而本地调用命令行的形式就报错了!

打开pycharm的setting,搜索 python console,右侧其中有一项,add content roots to pythonpath,默认pycharm是勾选上此项的。此项的意思是将内容的根路径加到python的环境变量路径下。
在这里插入图片描述

可以看到上图下面代码块里写着一堆代码,正是这段代码,我们才可以在pycharm中正确运行。

我们可以在test1.py里来看下sys.path,顺便打印看下结果。
在这里插入图片描述

pycharm控制台输出:

['F:\\pycharm\\python14\\package', 'F:\\pycharm\\python14', 
'D:\\python3.6\\python36.zip', 
'D:\\python3.6\\DLLs', 'D:\\python3.6\\lib', 'D:\\python3.6', 
'C:\\Users\\sy\\AppData\\Roaming\\Python\\Python36\\site-packages', 
'D:\\python3.6\\lib\\site-packages', 
'D:\\python3.6\\lib\\site-packages\\win32', 
'D:\\python3.6\\lib\\site-packages\\win32\\lib',
'D:\\python3.6\\lib\\site-packages\\Pythonwin']

实际通过命令行输出,应该没有’F:\pycharm\python14’ 这一项,因为这一项是pycharm中setting自动加上的!

实际控制台输出:

['F:\\pycharm\\python14\\package',
'D:\\python3.6\\python36.zip', 
'D:\\python3.6\\DLLs', 'D:\\python3.6\\lib', 'D:\\python3.6', 
'C:\\Users\\sy\\AppData\\Roaming\\Python\\Python36\\site-packages', 
'D:\\python3.6\\lib\\site-packages', 
'D:\\python3.6\\lib\\site-packages\\win32', 
'D:\\python3.6\\lib\\site-packages\\win32\\lib',
'D:\\python3.6\\lib\\site-packages\\Pythonwin']

sys.path是一个list。默然情况下python导入文件或者模块的话,他会先在sys.path里找模块的路径。如果没有的话,程序就会报错。可以看到,sys路径下有package的包名,而没有test4.py中引用test1.py模块。

而pycharm能够成功运行,正是因为它已经帮我们把项目的根路径添加到了python的环境变量中。所以我们仿照其类似写法也可以完成!

解决方案:

这里不得不说几个重要的python自带模块了,如下:

__file__ : python模块自身的名称
pycharm打印下__file__:

可以看到pycharm会将模块的绝对路径输出到控制台上。

在这里插入图片描述

在用命令行执行下看看:

在这里插入图片描述

python额外小知识:可以看到上图有一个__pycache__的文件夹,这个文件夹在pycharm的目录中,我们是看不到的,那么此文件夹的意义何在呢?点进去看下:

在这里插入图片描述

Python程序运行时不需要编译成二进制代码,而直接从源码运行程序,简单来说是,Python解释器将源码转换为字节码,然后再由解释器来执行这些字节码。而解释器的具体工作:
1、完成模块的加载和链接。
2、将源代码编译为PyCodeObject对象(即字节码),写入内存中,供CPU读取。
3、从内存中读取并执行,结束后将PyCodeObject写回硬盘当中,也就是复制到.pyc或.pyo文件中,以保存当前目录下所有脚本的字节码文件。
4、若再次执行该脚本,它先检查【本地是否有上述字节码文件】和【该字节码文件的修改时间是否在其源文件之后】,是就直接执行,否则重复上述步骤。
第一次执行代码的时候,Python解释器已经把编译的字节码放在__pycache__文件夹中,这样以后再次运行的话,如果被调用的模块未发生改变,那就直接跳过编译这一步,直接去__pycache__文件夹中去运行相关的 *.pyc 文件,大大缩短了项目运行前的准备时间。
CSDN来源:
https://blog.csdn.net/index20001/article/details/73501375

继续回归正题:

import sys,os   :  sys ,os模块是python系统自带模块

os模块: operate system 操作系统的意思,一般可以通过调用此模块来对系统进行相关操作

sys 模块: system 系统的意思,通过此模块来实现对python自定义包和模块的导入

有了以上两个知识点,我们可以对test4.py进行如下操作:

import sys,os

print(__file__)
print(os.path.abspath(__file__))
print(os.path.dirname(os.path.abspath(__file__)))
print(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

因为pycharm会对__file__进行路径补充,所以我们用命令行来执行test4.py

在这里插入图片描述

可以看到上图结果:

__file__             模块名字
test4.py           
os.path.abspath(__file__)     模块名字的绝对路径
F:\pycharm\python14\package\test4.py
os.path.dirname(os.path.abspath(__file__))    模块的包名绝对路径
F:\pycharm\python14\package

os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
F:\pycharm\python14                           项目本身的绝对路径

通过最后一步,我们可以将项目本身的路径直接拼入python的sys下

base_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(base_path)

验证究竟有没有加到我们的python环境变量中,最终代码为:

import sys, os

print(sys.path)
print(__file__)
print(os.path.abspath(__file__))
print(os.path.dirname(os.path.abspath(__file__)))
print(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
base_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(base_path)
print(sys.path)

通过命令行执行来看下:
在这里插入图片描述

有了以上的所有操作步骤,我们可以完美的将test1.py的a变量引入test4.py中了!来看下命令执行:


import sys, os
base_path = os.path.dirname(os.path.dirname(
                            os.path.abspath(__file__)))
sys.path.append(base_path)
----------------  sys拼接 一定要在自定义包引入之前定义   ----------------------------------
import package.test1 as test1       注意import的顺序。
print(test1.a)

在这里插入图片描述

成功!

写到这里涉及的知识点就已经这么多了。。。继续写。。。

3.包处于同级目录包和包同级,包1下的模块引入包2下的模块变量

在这里插入图片描述

可以看到,通过from test3 import c,pycharm中是正常输出的,控制台是报错的!原因实际和“2.模块处于同级目录(在同一包下)”的解释是一样的,只需要在引入自定义包之前,将我们项目的根路径加到python的系统变量中即可。

4.模块处于不同级目录包和模块同级,模块引入包下模块的变量
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

若属于3的情况,可以看到,不需要对python系统进行sys.append,可以正常使用import 或者 from 语句进行导入。

5.模块处于不同级目录包和模块同级,包下模块引入与包模块同级的变量

test3.py 中有:
c = 123455666
在packeage下的test1.py调用:
在这里插入图片描述

可以看到,通过from test3 import c,pycharm中是正常输出的,控制台是报错的!原因实际和“2.模块处于同级目录(在同一包下)”的解释是一样的,只需要在引入自定义包之前,将我们项目的根路径加到python的系统变量中即可。

import sys, os
base_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(base_path)
from test3 import c
print(c)

在这里插入图片描述

模块之前的相对引入

什么叫相对引入呢?相对路径大家可能听说过,相对引入和相对路径是一个道理的,比如 .代表的是当前目录,…代表的是上级目录,此处的写法就是相对路径,相对于某个文件来说,即相对!

实际上,在2.模块处于同级目录(在同一包下)中,还有一种相对引入的写法,但是对于test4.py引入test1.py来说,不能直接运行test4.py,否则会报错。来看下:
在这里插入图片描述

test1.py中有个a字符串:

test1.py
a = 'I am success !'

test4.py中,我用from .test1 import a来引入test1.py的变量a,注意,包下同级目录,我使用的是.test1 !!!!

test4.py

from .test1 import a
b = a + 'I am test4.py import .test1'

如果此时我直接将test4.py运行,并且打印b,就会报错!

在这里插入图片描述

ModuleNotFoundError: No module named '__main__.test1'; '__main__' is not 
a package

如果此时,我通过test2.py间接行调用test4.py中的b

from package.test4 import b
print(b)

无论是pycharm还是命令行,都是有成功运行的:

在这里插入图片描述

也就是说python对于相对引入来说,主动引入的函数不能作为主体去运行!

pycharm中可能会遇到的import报错

有人可能会遇到,当一个新项目导入到pycharm中,python代码的import有可能会报错,可以将项目设置为根路径,这样import错误即可消失,操作如下:
在这里插入图片描述

包和模块自身的额外小知识点

  1. 关于包下的 init.py

init,中文意思是初始化的意思,而__init__.py实际上就是作为包名来配合的,当我们调用一个包时,第一步python就会去调用__init__.py模块,所以,经常我们可以将包下的__init__.py中放入一些需要初始化的操作。

举个例子:
在这里插入图片描述

__init__.py:
init_a = 'I am __init__.py'
print(init_a)

在package包下定义了初始化的字符串。
而test2.py调用package下的test1.py中的a变量时:

test2.py:
from package.test1 import a
print(a)
test1.py:
a = 'I am success !'

可以看到下图运行结果,先输出了初始化模块中的字符串:

在这里插入图片描述

  1. 关于模块中的限定变量写法

依然是test2.py引入test1.py的变量:
在这里插入图片描述


test2.py:
from package.test1 import a,b,c
print(a)
print(b)
print(c)
test1.py:
__all__ = ['a','b']
a = 'I am success !'
b = 'I am fail !'
c = 'I am fuc***  you!!! !'

在test2中引入test1通过import单独引入三个变量,运行结果:

在这里插入图片描述

若将import 后面改成* ,则会限制变量。

在这里插入图片描述

而此处所说,就是因为在test1.py中有着__all__ = [] ,这样的写法可以限定住import * 的限制,test4.py import *时,则会被限制住骂人的语句!

import 模块的万金油方法

上面说了这么多种情况,如果你实在是记不住,那么请记住一点,万金油的import方式,就是在你所有模块的入口模块处,以下面代码为例,将你项目本身的绝对路径拼入到python 的系统path下,这样自定义的包一定不会出错!!!

import sys, os
base_path = os.path.dirname(os.path.dirname(
                            os.path.abspath(__file__)))
sys.path.append(base_path)

有想学python的同学,欢迎关注公号:

在这里插入图片描述

python模块详解 各个模块的详解 核心模块 1.1. 介绍 1.2. _ _builtin_ _ 模块 1.3. exceptions 模块 1.4. os 模块 1.5. os.path 模块 1.6. stat 模块 1.7. string 模块 1.8. re 模块 1.9. math 模块 1.10. cmath 模块 1.11. operator 模块 1.12. copy 模块 1.13. sys 模块 1.14. atexit 模块 1.15. time 模块 1.16. types 模块 1.17. gc 模块 更多标准模块 2.1. 概览 2.2. fileinput 模块 2.3. shutil 模块 2.4. tempfile 模块 2.5. StringIO 模块 2.6. cStringIO 模块 2.7. mmap 模块 2.8. UserDict 模块 2.9. UserList 模块 2.10. UserString 模块 2.11. traceback 模块 2.12. errno 模块 2.13. getopt 模块 2.14. getpass 模块 2.15. glob 模块 2.16. fnmatch 模块 2.17. random 模块 2.18. whrandom 模块 2.19. md5 模块 2.20. sha 模块 2.21. crypt 模块 2.22. rotor 模块 2.23. zlib 模块 2.24. code 模块 线程和进程 3.1. 概览 3.2. threading 模块 3.3. Queue 模块 3.4. thread 模块 3.5. commands 模块 3.6. pipes 模块 3.7. popen2 模块 3.8. signal 模块 数据表示 4.1. 概览 4.2. array 模块 4.3. struct 模块 4.4. xdrlib 模块 4.5. marshal 模块 4.6. pickle 模块 4.7. cPickle 模块 4.8. copy_reg 模块 4.9. pprint 模块 4.10. repr 模块 4.11. base64 模块 4.12. binhex 模块 4.13. quopri 模块 4.14. uu 模块 4.15. binascii 模块 文件格式 5.1. 概览 5.2. xmllib 模块 5.3. xml.parsers.expat 模块 5.4. sgmllib 模块 5.5. htmllib 模块 5.6. htmlentitydefs 模块 5.7. formatter 模块 5.8. ConfigParser 模块 5.9. netrc 模块 5.10. shlex 模块 5.11. zipfile 模块 5.12. gzip 模块 邮件和新闻消息处理 6.1. 概览 6.2. rfc822 模块 6.3. mimetools 模块 6.4. MimeWriter 模块 6.5. mailbox 模块 6.6. mailcap 模块 6.7. mimetypes 模块 6.8. packmail 模块 6.9. mimify 模块 6.10. multifile 模块 网络协议 7.1. 概览 7.2. socket 模块 7.3. select 模块 7.4. asyncore 模块 7.5. asynchat 模块 7.6. urllib 模块 7.7. urlparse 模块 7.8. cookie 模块 7.9. robotparser 模块 7.10. ftplib 模块 7.11. gopherlib 模块 7.12. httplib 模块 7.13. poplib 模块 7.14. imaplib 模块 7.15. smtplib 模块 7.16. telnetlib 模块 7.17. nntplib 模块 7.18. SocketServer 模块 7.19. BaseHTTPServer 模块 7.20. SimpleHTTPServer 模块 7.21. CGIHTTPServer 模块 7.22. cgi 模块 7.23. webbrowser 模块 国际化 8.1. locale 模块 8.2. unicodedata 模块 8.3. ucnhash 模块 多媒体相关模块 9.1. 概览 9.2. imghdr 模块 9.3. sndhdr 模块 9.4. whatsound 模块 9.5. aifc 模块 9.6. sunau 模块 9.7. sunaudio 模块 9.8. wave 模块 9.9. audiodev 模块 9.10. winsound 模块 数据储存 10.1. 概览 10.2. anydbm 模块 10.3. whichdb 模块 10.4. shelve 模块 10.5. dbhash 模块 10.6. dbm 模块 10.7. dumbdbm 模块 10.8. gdbm 模块 工具和实用程序 11.1. dis 模块 11.2. pdb 模块 11.3. bdb 模块 11.4. profile 模块 11.5. pstats 模块 11.6. tabnanny 模块 其他模块 12.1. 概览 12.2. fcntl 模块 12.3. pwd 模块 12.4. grp 模块 12.5. nis 模块 12.6. curses 模块 12.7. termios 模块 12.8. tty 模块 12.9. resource 模块 12.10. syslog 模块 12.11. msvcrt 模块 12.12. nt 模块 12.13. _winreg 模块 12.14. posix 模块 执行支持模块 13.1. dospath 模块 13.2. macpath 模块 13.3. ntpath 模块 13.4. posixpath 模块 13.5. strop 模块 13.6. imp 模块 13.7. new 模块 13.8. pre 模块 13.9. sre 模块 13.10. py_compile 模块 13.11. compileall 模块 13.12. ihooks 模块 13.13. linecache 模块 13.14. macurl2path 模块 13.15. nturl2path 模块 13.16. tokenize 模块 13.17. keyword 模块 13.18. parser 模块 13.19. symbol 模块 13.20. token 模块 其他模块 14.1. 概览 14.2. pyclbr 模块 14.3. filecmp 模块 14.4. cmd 模块 14.5. rexec 模块 14.6. Bastion 模块 14.7. readline 模块 14.8. rlcompleter 模块 14.9. statvfs 模块 14.10. calendar 模块 14.11. sched 模块 14.12. statcache 模块 14.13. grep 模块 14.14. dircache 模块 14.15. dircmp 模块 14.16. cmp 模块 14.17. cmpcache 模块 14.18. util 模块 14.19. soundex 模块 14.20. timing 模块 14.21. posixfile 模块 14.22. bisect 模块 14.23. knee 模块 14.24. tzparse 模块 14.25. regex 模块 14.26. regsub 模块 14.27. reconvert 模块 14.28. regex_syntax 模块 14.29. find 模块
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值