一、关于模块
在学习函数之后,我们可以重复使用函数从而减少代码的长度,但是随着程序代码越来越多,函数也会越来越多,代码也会越来越长,越来越难以维护,而为了代码的可维护性,我们可以把函数分组,放到不同的文件里,这样的话,文件和文件就可以相互调用对方的函数,从而减少代码的长度,很多编程语言都会采用这种组织代码的方式,在Python中,.py文件就是充当的这样的角色,而一个py文件就叫做模块(module)
通俗来说,模块就是一组Python代码的集合,可以使用其他模块,也可以被其他模块使用
使用模块的好处:
提高了代码的可维护性
有了模块之后,编写代码不需要从零编写,当一个模块编写完毕,就可以被其他地方引用,从而提高代码开发效率
可以避免函数名称和变量名冲突,相同名称的函数和变量完全可以保存在不同的模块中,因此在编写模块时,不需要考虑名称会与其他模块冲突,但是要注意不要与内置函数名称冲突,点击这里查看Python所有内置函数
- 除了我们自己编写的模块,我们还可以引用Python的
内置模块和第三方模块
- 为了避免模块名冲突,Python还引入了按目录来组织模块的方法,这种方法称为
包(Package)
- 现在来看几个关于模块的例子:
当前有一个test.py文件,而这个文件的模块名就叫做test,同样的有一个aaa.py文件,它的模块名就叫做aaa
此时,这两个模块名和其他的模块名冲突了,而现在我们就可以通过包来组织模块,避免冲突,方法就是加一个顶层包名,例如引用顶层包名mycompany,按照如下目录存放:
mycompany: > __init__.py > test.py > aaa.py
引入了包后,只要顶层包名不和其他的冲突,那么所有模块都不会与别人冲突,现在test.py模块的名称就变成了mycompany.test,同样aaa.py模块变成了mycompany.aaa,这样就避免了模块名冲突
可以看到,在添加顶层包名后,目录中还多了一个文件__init__.py,这个文件是必须存在的,否则Python就会把这个目录当作普通目录看,而不是一个包
同样的,也可以使用多级目录,组成多级层次的包结构,例如:
mycompany: > web > __init__.py > aaa.py > bbb.py > __init__.py > test.py > aaa.py 根据上面的例子,bbb.py的模块名就是mycompany
根据上面的例子,bbb.py的模块名就是mycompany.web.bbb,test.py的模块名就是mycompany.test,虽然在mycompany和web下都有aaa模块,但是模块名是不一样的,一个是mycompany.aaa,另一个是mycompany.web.aaa
注意事项:
在创建模块时需要注意命名,不能和Python自带的模块名称冲突,例如系统中自带了sys模块,如果自己再定义一个sys.py模块的话,那么自带的sys模块就无法导入了,如果不确定的话,可以在Python的交互环境中执行import 模块名来确认,成功则说存在此模块
需要注意的是:__init__.py本身就是一个模块,它的模块名就是mycompany,所以这个__init__.py可以是空文件,也可以有Python代码
模块名要遵循Python变量命名规范,不要使用中文、特殊字符
二、使用模块
- Python内置了许多有用的模块,只要安装完Python,这些模块就可以直接使用
- 以内置模块
sys
为例,创建一个hello
模块==(hello.py文件)==
#!/usr/bin/env python3 #注释行,这行可以直接让此py文件在linux上执行 # -*- coding: utf-8 -*- #注释行,表示此py文件本身使用标准UTF-8编码 ' a test module ' #这是一串字符串,表示模块的文档注释,任何代码的第一个字符串都被看做是模块的文档注释 __author__ = 'Michael Liao' #使用__author__变量可以把作者写进入,这样在公开源码后就可以知道这是谁写的 import sys def test(): args = sys.argv if len(args)==1: print('Hello, world!') elif len(args)==2: print('Hello, %s!' % args[1]) else: print('Too many arguments!') if __name__=='__main__': test()
- 上面的代码中1—6行就是Python模块的标准写法,虽然并没有说强制要求这样写,但是最好还是按标准编写
- 在第8行开始就是真正的代码部分:
(1)使用sys内置模块的第一步就是使用"import sys"导入sys模块,所以在第8行中导入了模块,在导入模块后,会创建一个变量"sys",改变量指向了"sys"模块,通过这个变量就可以访问"sys"模块的所有功能
import sys
(2)创建test函数后,第11行中,我们使用了’sys’模块的’argv’变量,此变量使用列表存储了命令行的所有参数,'argv’至少有一个元素,和shell脚本相同,第一个元素指向的永远是py文件本身(即py文件的名称),例如:
#执行脚本 python3 hello.py #sys.argv变量的值就是 ['hello.py'] #同样的,多个参数 python3 hello.py aaa #那么sys.argv变量就变成了 ['hello.py','aaa']
(3)最后来看代码的19行和20行,这两行代码我们在其他的py文件中肯定也看到过,这个if判断语句最简单的解释就是:如果直接执行包含下面if判断的模块,则该语句会判断为真,然后运行语句下的代码,反之如果是通过导入该模块到其他的py脚本运行的,则语句判断为假,下面的代码不运行
if __name__=='__main__': test()
(4)利用centos的命令行执行test.py
[root@centos-1 ~]# python3 hello.py Hello, world! [root@centos-1 ~]# python3 hello.py zhangsan Hello, zhangsan!
(5)进入centos交互环境执行test.py
[root@centos-1 ~]# python3 Python 3.9.9 (main, May 10 2022, 15:32:30) [GCC 4.8.5 20150623 (Red Hat 4.8.5-16)] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import hello #导入模块 >>> hello.test() #执行模块中的函数test Hello, world!
三、作用域
在一个模块中,我们可能会定义很多函数和变量,在这些函数和变量中,我们希望有些可以给其他人使用,有些我们只希望在模块内部使用,而在Python中可以通过_前缀来实现这样的效果
正常在模块中的函数和变量名是公开(public)的,可以直接被引用,例如:aaa,b2,cc_33这样的自定义变量,而在上面使用的__name__变量是特殊变量,可以直接被引用但是有着特殊用途,这样的__xx__格式的变量还有__author__、__doc__等,在设定变量时不用使用这样格式的变量名
除了上面的普通变量和特殊变量,还有_xx和__xx这些格式,这样格式的变量是非公开的(private)。因为在Python中并没有一种方法完全限制访问非公开函数或者变量,所以说虽然是非公开的,但是其实也可直接进行引用,只是说从编程习惯来说不应该进行引用,例如:_aaa,__aaa等
既然非公开函数或者变量不引用被引用,那么他们的作用是什么,下面来看几个案例:
[root@centos-1 ~]# cat hello.py # -*- coding: utf-8 -*- def _test_1(name): return 'Hello,%s' % name def _test_2(name): return 'bay,%s' % name def test(name): if len(name) > 3: return _test_1(name) else: return _test_2(name) #保存退出 [root@centos-1 ~]# cat aaa.py #!/usr/bin/env python3 # -*- conding: utf-8 -*- import hello print(hello.test('zhangsan')) print(hello.test('li')) #保存退出 [root@centos-1 ~]# python3 aaa.py Hello,zhangsan bay,li ————————————————————分割线———————————————————— 我们只在'hello'模块中公开'test'函数,其他的函数都被隐藏起来了,这样在调用'test'函数时就无需关心调用函数细节,这也是一种代码封装和抽象的方法
注意:外部不需要引用的函数可以全部定义成非公开的(private),只有外部需要引用的函数再定义为公开(public)
三、安装第三方模块
在Python中,除了内置模块、自定义模块,还可以通过包管理工具pip安装第三方模块,如果是mac或者linux系统,那么安装pip这个过程就可以跳过,而windows需要在安装python时``勾选pip选项和Add python.exe to Path`即可,如果忘记的话,可以重新运行安装程序选中安装
在windows中,打开cmd命令行,输入pip后按回车,如果提示未找到命令,就说明没有安装。而在mac或者linux上中,可能会同时存在Python2版本和3版本,使用python3的话,那么对应的pip命令应该是pip3
一般来说,第三方库都会在Python官方的pypi.python.org网站注册,要安装一个第三方库,必须先知道该库的名称,可以在官网或者pypi上搜索,比如Pillow的名称叫Pillow,因此,安装Pillow的命令就是:
pip install Pillow #耐心等待下载并安装后,就可以使用Pillow了。
(1)安装常用模块
在使用Python时,经常需要用到很多第三方库,例如上面提到的Pillow,以及MySQL驱动程序,Web框架Flask,科学计算Numpy等。用pip一个一个安装费时费力,还需要考虑兼容性。
廖雪峰大神推荐直接使用Anaconda,这是一个基于Python的数据处理和科学计算平台,它已经内置了许多非常有用的第三方库,我们装上Anaconda,就相当于把数十个第三方模块自动安装好了,非常简单易用。
可以从Anaconda官网下载GUI安装包,安装包有500~600M,所以需要耐心等待下载。下载后直接安装,Anaconda会把系统Path中的python指向自己自带的Python,并且,Anaconda安装的第三方模块会安装在Anaconda自己的路径下,不影响系统已安装的Python目录。
安装Anaconda:
- 安装好Anaconda后,会多出一个
powershell
,打开,输入python,可以看到Anaconda的信息,不过这个python是3.9的
(base) PS C:\Users\RZY> python Python 3.9.7 (default, Sep 16 2021, 16:59:28) [MSC v.1916 64 bit (AMD64)] :: Anaconda, Inc. on win32 Type "help", "copyright", "credits" or "license" for more information. >>>import numpy #直接导入模块,发现可以直接导入 >>>
(2)模块搜索路径
- 当我们试图加载一个模块时,Python会在指定的路径下搜索对应的.py文件,如果找不到,就会报错:
>>> import mymodule Traceback (most recent call last): File "<stdin>", line 1, in <module> ImportError: No module named mymodule
默认情况下,Python解释器会搜索当前目录、所有已安装的内置模块和第三方模块,搜索路径存放在sys模块的path变量中:
>>> import sys >>> sys.path ['', 'C:\\Users\\RZY\\AppData\\Local\\Programs\\Python\\Python310\\python310.zip', 'C:\\Users\\RZY\\AppData\\Local\\Programs\\Python\\Python310\\DLLs', 'C:\\Users\\RZY\\AppData\\Local\\Programs\\Python\\Python310\\lib', 'C:\\Users\\RZY\\AppData\\Local\\Programs\\Python\\Python310', 'C:\\Users\\RZY\\AppData\\Local\\Programs\\Python\\Python310\\lib\\site-packages']
- 如果我们要添加自己的搜索目录,有两种方法:
(1)直接修改
sys.path
,添加要搜索的目录:
>>> sys.path.append('D:\工作\work\py') >>> sys.path ['', 'C:\\Users\\RZY\\AppData\\Local\\Programs\\Python\\Python310\\python310.zip', 'C:\\Users\\RZY\\AppData\\Local\\Programs\\Python\\Python310\\DLLs', 'C:\\Users\\RZY\\AppData\\Local\\Programs\\Python\\Python310\\lib', 'C:\\Users\\RZY\\AppData\\Local\\Programs\\Python\\Python310', 'C:\\Users\\RZY\\AppData\\Local\\Programs\\Python\\Python310\\lib\\site-packages', 'D:\\工作\\work\\py']
注意:这种方法是在运行时修改,运行结束后失效。
(2)设置环境变量PYTHONPATH,该环境变量的内容会被自动添加到模块搜索路径中。设置方式与设置Path环境变量类似。注意只需要添加你自己的搜索路径,Python自己本身的搜索路径不受影响。