购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

2.7 Python模块

模块是一个包含所有定义的函数和变量的文件,其后缀名是.py。模块可以被别的程序引入,以使用该模块中的函数等功能。这也是使用Python标准库的方法。模块让我们能够有逻辑地组织Python代码段,把相关的代码分配到一个模块里能让代码更好用、更易懂。

模块能定义函数、类和变量,模块里也能包含可执行的代码。例如:

     #新建模块文件modle_1.py
     def p_func(arg):
         print('Hello',arg)
         return
     
     #新建主模块文件main.py
     from modle_1 import p_func          #导入模块modle_1中的p_func函数
     
     if__name__=="__main__":            #判断是否为主程序执行口
         p_func('Python')

运行程序,输出如下:

     hello python

2.7.1 引入模块

模块定义好后,可以使用import语句引入模块,语法格式为

     import module1,[module2[,…moduleN]]

如果要引用模块math,则可以在文件最开始用import math引入。在调用math模块中的函数时,必须使用“模块名.函数名”。不管执行了多少次import,一个模块只会被导入一次,这样可以防止导入模块被重复执行。

     from …  import语句:

Python中的from语句可从模块中导入一个指定的部分到当前命名空间中,语法如下:

     from modname import name1,name2,…,nameN
     from mod import func_1            #导入mod模块中的func_1函数

这个声明不会把整个mod模块导入到当前命名空间中,它只会将mod里的func_1单个引入到执行这个声明的模块的全局符号表。

     from…  import *

这样会把模块中的所有内容导入到当前命名空间,一般不建议使用,因为会消耗内存空间,也容易出现未预知的问题。

2.7.2 搜索路径

当导入一个模块后,Python解析器对模块位置的搜索顺序是:

当前目录→shell变量PYTHONPATH下的每个目录→Python模块路径目录。

模块的搜索路径存储在system模块的sys.path变量中,包括当前目录、Python路径和安装过程决定的默认目录。

     import sys
     print(sys.path)
     ['','D:\\Anaconda3\\python36.zip','D:\\Anaconda3\\DLLs','D:\\Anaconda3\\lib','D:\\
     Anaconda3','C:\\Users\\ASUS\\AppData\\Roaming\\Python\\Python36\\site-packages','D:\\
     Anaconda3\\lib\\site-packages','D:\\Anaconda3\\lib\\site-packages\\Babel-2.5.0-py3.6.
     egg','D:\\Anaconda3\\lib\\site-packages\\win32','D:\\Anaconda3\\lib\\site-packages\\
     win32\\lib','D:\\Anaconda3\\lib\\site-packages\\Pythonwin','D:\\Anaconda3\\lib\\site-
     packages\\IPython\\extensions','C:\\Users\\ASUS\\.ipython']

其中,空字符串表示当前工作目录。当安装第三方模块的时候,如果不是按照标准方式安装,为了能够引用这些模块,必须将这些模块的安装路径添加到sys.path中,添加方法如下:

(1)最简单的方法是在sys.path的某个目录下添加路径配置文件,最常见的就是在…/site-package/目录下,路径配置文件的扩展名为“.pth”,其中的每一行包含一个单独的路径,该路径会添加到sys.path列表中,“.pth”中的路径可以是绝对路径也可以是相对路径,如果是相对路径则是相对于包含“.pth”文件的路径而言的。

     import sys
     print(sys.path)  #默认搜索路径
     [root@python site-packages]#vim/media/aa.py
     #在site-packages下新建配置文件system.pth,内容为需要添加的模块路径
     [root@python site-packages]#cat system.pth
     /media
     #在/media目录下新建模块aa.py
     [root@python site-packages]#cat/media/aa.py
     
     def munit(x,y):
         print('sun:',x+y)
         return x+y
     ['',
      'D:\\Anaconda3\\python36.zip',
      'D:\\Anaconda3\\DLLs',
      'D:\\Anaconda3\\lib',
      'D:\\Anaconda3',
      'C:\\Users\\ASUS\\AppData\\Roaming\\Python\\Python36\\site-packages',
      'D:\\Anaconda3\\lib\\site-packages',
      'D:\\Anaconda3\\lib\\site-packages\\Babel-2.5.0-py3.6.egg',
      'D:\\Anaconda3\\lib\\site-packages\\win32',
      'D:\\Anaconda3\\lib\\site-packages\\win32\\lib',
      'D:\\Anaconda3\\lib\\site-packages\\Pythonwin',
      'D:\\Anaconda3\\lib\\site-packages\\IPython\\extensions',
      'C:\\Users\\ASUS\\.ipython']
     
     import aa        #导入模块aa
     aa.munit(1,2)         #执行模块中的函数
     sun:3
     3

(2)另一种方法是在Python标准库中修改site.py文件,并编辑sys.path。除非使用了-S开关选项,否则site.py在Python解释器加载时会自动被引入(执行),作用是加载site-packages中的包和模块到Python的sys.path里面。

     import aa
    ---------------------------------------------------------------------
     ModuleNotFoundError           Traceback(most recent call last)
    <ipython-input-18-510651a95b7a> in<module>()
    ---->1 import aa
     
     ModuleNotFoundError:No module named 'aa'
     
     import sys
     sys.path
     ['',
      'D:\\Anaconda3\\python36.zip',
      'D:\\Anaconda3\\DLLs',
     ...
      'D:\\Anaconda3\\lib\\site-packages\\IPython\\extensions',
      'C:\\Users\\ASUS\\.ipython']
     
     import sys
     sys.path.append("/media")   #添加模块路径到搜索路径中
     sys.path
     ['',
      'D:\\Anaconda3\\python36.zip',
      'D:\\Anaconda3\\DLLs',
      'D:\\Anaconda3\\lib',
     ...
      'C:\\Users\\ASUS\\.ipython',
      '/media']
     import aa
     aa.munit(2,3)
     sun:5
     5

(3)修改PYTHONPATH环境变量,一般不推荐使用此方法。

     set PYTHONPATH=/usr/local/lib/python

2.7.3__name__属性

一个模块被另一个程序第一次引入时,其主程序将运行。如果想在模块被引入时,模块中的某一程序块不执行,可以用__name__属性使该程序块仅在该模块自身运行时执行。例如:

     if__name__== '__main__':
        print('程序自身在运行')
     else:
        print('我来自另一模块')

运行程序,输出如下:

     程序自身在运行
     
     import using_name

运行程序,输出如下:

     我来自另一模块

由结果可看出,每个模块都有一个__name__属性,当其值是'__main__'时,表明该模块自身在运行,否则是被引入。__name__与__main__底下是双下画线。

2.7.4 命名空间和作用域

变量是拥有匹配对象的名字(标识符)。命名空间是一个包含了变量名称(键)和相应的对象(值)的字典。一个Python表达式可以访问局部命名空间和全局命名空间里的变量。如果一个局部变量和一个全局变量重名,则局部变量会覆盖全局变量。每个函数都有自己的命名空间。类的方法的作用域规则和通常函数的一样。

Python会智能地猜测一个变量是局部的还是全局的,它假设任何在函数内赋值的变量都是局部的。因此,如果要给函数内的全局变量赋值,必须使用global语句。global VarName的表达式会告诉Python, VarName是一个全局变量,这样Python就不会在局部命名空间里寻找这个变量了。

例如,在全局命名空间里定义一个变量Money,再在函数内给变量Money赋值。Python会假定Money是一个局部变量,由于并没有在访问前声明一个局部变量Money,结果则会出现一个UnboundLocalError的错误。此时取消global语句的注释就能解决这个问题。

     Money=2000      #定义全局变量
     def addmoney():
         #global Money
         Money=Money+1        #函数内不能直接调用全局变量,必须用global来声明全局变量
     print(Money)
     2000
     
     addmoney()
     print(Money)
     UnboundLocalError            Traceback(most recent call last)
    <ipython-input-24-a3819a35e2e7> in<module>()
    ----> 1 addmoney()
     UnboundLocalError:local variable 'Money'referenced before assignment

2.7.5 相关函数

下面介绍几个与模块相关的函数。

1.dir()函数

dir()函数一个排好序的字符串列表,内容是一个模块里定义过的名字。返回的列表容纳了在一个模块里定义的所有模块、变量和函数。例如:

     import fibo,sys
     dir(fibo)
     ['__name__','fib','fib2']
     
     dir(sys)
     ['__displayhook__',
      '__doc__',
      '__excepthook__',
      '__interactivehook__',
    ...
      'version_info',
      'warnoptions',
      'winver']

如果没有给定参数,那么dir()函数会罗列出当前定义的所有名称。

     a=[1,2,3,4,5]
     import fibo
     fib=fibo.fib
     dir()          #得到一个当前模块中定义的属性列表
     ['__builtins__','__name__','a','fib','fibo','sys']
     a=5                        #建立一个新的变量'a'
     dir()
     ['__builtins__','__doc__','__name__','a','sys']
     del a                      #删除变量名a
     dir()
     ['__builtins__','__doc__','__name__','sys']
2.globals()和locals()函数

根据调用地方的不同,globals()和locals()函数可被用来返回全局和局部命名空间里的名字。如果在函数内部调用locals(),则返回的是所有能在该函数里访问的命名。如果在函数内部调用globals(),则返回的是所有在该函数里能访问的全局名字。两个函数的返回类型都是字典。所以能用keys()函数摘取名字。

3.reload()函数

当一个模块被导入到一个脚本,模块顶层部分的代码只会被执行一次。因此,如果需要重新执行模块里顶层部分的代码,则可以用reload()函数。该函数会重新导入之前导入过的模块。

4.Python中的包

包是一个分层次的文件目录结构,它定义了一个由模块、子包和子包下的子包等组成的Python的应用环境。

简单来说,包就是文件夹,但该文件夹下必须存在__init__.py文件,该文件的内容可以为空。__int__.py用于标识当前文件夹是一个包。

【例2-16】 Python中的包实例演示。

     #首先在根目录下创建两个目录,分别创建模块aa,bb
     [root@python media1]#ls/media/
     aa.py__pycache__
     [root@python media1]#ls/media1/
     bb.py__pycache__
     #在aa和bb模块下创建函数:
     [root@python media1]#cat/media/aa.py
     
     def munit(x,y):
         print('sun:',x+y)
         return x+y
     [root@python media1]#cat/media1/bb.py
     
     def mule(x,y):
         return x * * y
     
     #调用模块
     [root@python~]#cat init.py
     import sys
     sys.path.append("/media")
     from aa import munit
     print(sys.path)
     s=munit(3,4)
     print(s)
     [root@python~]#python3 init.py

运行程序,输出如下: raTJT1nnOw11Do+8YL4IR49OlRZb9NaTZJvlo5+7RjYjtJvwHHmyxMU6sGe+5/I5

     ['',
      'D:\\Anaconda3\\python36.zip',
      'D:\\Anaconda3\\DLLs',
      'D:\\Anaconda3\\lib',
      'D:\\Anaconda3',
      'C:\\Users\\ASUS\\AppData\\Roaming\\Python\\Python36\\site-packages',
      'D:\\Anaconda3\\lib\\site-packages',
      'D:\\Anaconda3\\lib\\site-packages\\Babel-2.5.0-py3.6.egg',
      'D:\\Anaconda3\\lib\\site-packages\\win32',
      'D:\\Anaconda3\\lib\\site-packages\\win32\\lib',
      'D:\\Anaconda3\\lib\\site-packages\\Pythonwin',
      'D:\\Anaconda3\\lib\\site-packages\\IPython\\extensions',
      'C:\\Users\\ASUS\\.ipython',
      '/media']
点击中间区域
呼出菜单
上一章
目录
下一章
×