Python之模块和包学习

模块简介

python是由一系列的模块组成的,每个模块就是一个py为后缀的文件,同时模块也是一个命名空间,从而避免了变量名称冲突的问题。模块我们就可以理解为lib库,如果需要使用某个模块中的函数或对象,则要导入这个模块才可以使用,除了系统默认的模块(内置函数)不需要导入外。

导入直接使用如下语法:  import 模块名称 (不要.py后缀)

这样导入成功后,就可以在另外一个模块中使用被导入模块的功能函数或对象。

举例如下,比如在F:\Pro-files\workspace\myPython目录下建立com.homer.python模块:module_1.py:

[python] view plaincopyprint?

  1. # -*- coding:utf-8 -*-
  2. ‘‘‘‘‘module_1.py‘‘‘
  3. name = "ithomer"
  4. url = "http://blog.ithomer.net"

上面第一行是指定编码格式,因为python默认是按照ascii编码来处理的,因此就无法处理非英文语言,通过指定编码就可以实现国际化效果,即容许中文注释。第二行是注释信息,使用”’进行注释。然后,我们通过F:\Pro-files\workspace\myPython\com\homer目录进入到python的命令行模式,这样就可以将当前目录作为工作目录,从而也就可以顺利的找到了module_1这个模块了,如下:

[python] view plaincopyprint?

  1. :\Pro-files\workspace\myPython\com\homer>python
  2. Python 3.3.3 (v3.3.3:c3896275c0f6, Nov 18 2013, 21:19:30) [MSC v.1600 64 bit (AMD64)] on win32
  3. Type "help", "copyright", "credits" or "license" for more information.
  4. >>>

此时如果我们直接输入print(url),系统则会报错,url变量未定义:

[python] view plaincopyprint?

  1. >>> print(url)
  2. Traceback (most recent call last):
  3. File "<stdin>", line 1, in <module>
  4. NameError: name ‘url‘ is not defined
  5. >>>

所以我们需要先导入module_1的内容才算定义了url变量,不过要注意的是导入的模块的变量并不是定义在顶层命名空间,而是在模块的命名空间中,因此使用如下方式导入后的打印变量如下:

[python] view plaincopyprint?

  1. >>> import module_1
  2. >>> print(module_1.url)
  3. http://blog.ithomer.net

如果直接使用print(url),仍然还是会报url未定义的错误,原因就是上面说到的命名空间的问题。如果想要直接在顶层命名空间中使用该变量,可以使用如下导入方式:

[python] view plaincopyprint?

  1. >>> from module_1 import url
  2. >>> print(url)
  3. http://blog.ithomer.net

这样就可以将module_1模块中的url变量导入到顶层命名空间了,直接使用变量也就不会报错了。当然我们也可以为导入的变量重命名,如下把url重命名为myurl:

[python] view plaincopyprint?

  1. >>> from module_1 import url as myurl
  2. >>> print(myurl)
  3. http://blog.ithomer.net

这样就可以将url的值赋给myurl这个变量了,因为是使用了from…import语句,因此是将变量绑定在顶层命名空间,我们也就可以直接使用变量名了。

需要注意的是无论是使用import还是使用from..import的方式导入模块,其实都是在告诉python解释器要加载指定的模块,并执行模块中的所有语句,因此如果模块中有类似print的语句时,我们在导入的过程中也会看到这些语句的输出。

对于每个模块的导入,python解释器只会导入一次,即使重复使用import和from…import语句,也只有在PVM检测到该模块没有被导入时才执行导入动作。即使后来你修改了模块的源代码,但没有重启PVM,python解释器仍然是使用之前导入的内容在处理。如果需要重新载入修改后的源码,一是退出python的交互模式后再进入,二是直接使用reload语句,如下:

[python] view plaincopyprint?

  1. >>> from imp import reload
  2. >>> reload(module_1)
  3. <module ‘module_1‘ from ‘.\\module_1.py‘>

我们可以看到系统提示重新加载了module_1模块的源文件,我们修改内容后使用该方法重新导入后再执行就可以看到修改后的内容。

模块导入和执行

模块作为python语言中的基本单元,可以用来编写公用库函数或对象以便重复使用。同时模块还可以作为独立文件进行运行,之前也已经提到,只要是导入了模块文件,那么PVM就会依次执行模块文件中的所有语句。本篇主要介绍模块使用的一些进阶,首先定义一个模块module_2.py,内容如下:

[python] view plaincopyprint?

  1. # -*- encoding:utf-8 -*-
  2. ‘‘‘‘‘module_2.py模块的内容‘‘‘
  3. print(__name__)
  4. def sum(a,b):
  5. return a+b
  6. if __name__ == "__main__":
  7. import sys
  8. print(sys.argv[0])
  9. a = int(sys.argv[1])
  10. b = int(sys.argv[2])
  11. print(sum(a,b))

上面的这段代码基本上就包含了本篇文章要说的内容了:

__name__变量说明

__name__是一个全局变量,在模块内部是用来标识模块的名称的。上面的例子中有一个打印__name__变量的语句,比如我们在python的交互模式下执行导入可以看到如下结果:

  1. >>>import module_2
  2. module_2

可以看到,通过使用import的方式导入模块后,打印的__name__值就是我们刚才说的模块的名称。另外如果是通过python解释器直接执行模块,则__name__会被设置为__main__这个字符串值,如下:

[python] view plaincopyprint?

  1. F:\Pro-files\workspace\myPython\com\homer>python module_2.py 2 3
  2. __main__
  3. module_2.py
  4. 5

我们通过windows命令行直接执行module_2这个模块文件,可以看到的结果输入如上,打印的__name__值为__main__。通过这个特性我们可以将一个模块文件既当做普通的lib库供其他模块使用,又可以当做一个顶层执行文件进行执行,只是使用方式不一样而已。

1、当成lib库使用时,只需要在其他模块中使用import导入该模块即可(module_2)

2、当成执行模块时,通过python解释器直接运行该模块,然后在模块文件中最后写上上面例子中的if判断语句段即可(__main__)

通过__name__变量来区分是执行模块还是导入模块其实就非常类似java中的main函数了,不同的是java中是约定的方法名称,而python中约定是变量名称,异曲同工之效。

参数传递

参数传递主要是指作为执行模块时需要传递的参数,通过python解释器执行某一个执行模块传递参数的使用如下:

F:\Pro-files\workspace\myPython\com\homer>python 模块名称(包含.py后缀)  参数1  参数2  参数3 ....

对于上面给定的例子执行就是:

[python] view plaincopyprint?

  1. F:\Pro-files\workspace\myPython\com\homer>python module_2.py 2 3
  2. __main__
  3. module_2.py
  4. 5

python解释器会将所有传递的参数存储在sys.argv这个列表中,所有的参数都被当成字符串进行处理。同时即使不传递任何参数,也会有一个默认的参数sys.argv[0]标识当前模块的名称(如module_2.py),所以我们自己使用的参数都是从sys.argv[1]开始的,下标1表示第一个传递的参数,依次类推(如 2 3)。

模块包和搜索路径

一个python文件就是一个模块,使用独立的命名空间,但实际使用过程中单单用模块来定义python功能显然还不够。因为一个大型的系统几千上万个模块是很正常的事情,如果都聚集在一起显然不好管理并且有命名冲突的可能,因此python中也出现了一个包的概念。

(package),通过使用“点模块名称”创建Python模块命名空间的一种方法。例如,模块名称 A.B 表示一个在名为 A的包下的名为B的子模块。就像使用模块让不同模块的作者无需担心彼此全局变量名称(冲突)一样,点模块名称让多模块包的作者无需担心彼此的模块名称(冲突)。模块包在文件系统中的表示就是一系列目录的集合,通过目录的层级结构形成模块包的层级结构,最终的模块文件就位于最后的目录中。比如定义一个简单的模块在包pkg下,那么执行如下步骤:

1、在F:\Pro-files\workspace\目录下建立一个目录,名称是myPython

2、在myPython下建立包com.homer,并在项目目录myPython/com/homer下com和com.homer下分别创建__init__.py的模块,内容为空即可

3、在myPython/com/homer目录下建立一个python模块module_3.py,内容如下:

[python] view plaincopyprint?

  1. # -*- encoding:utf-8 -*-
  2. ‘‘‘‘‘pkg.module_3.py模块的内容‘‘‘
  3. print("Hello World")
  4. def func1():
  5. print("This is funciton one")

注意第2步,必须要在每一个包目录下建立一个__init__.py的模块,这个是python的规定,用来告诉python解释器将该目录当成一个内容包,即该目录是一个包,里面包含了python模块的。这个是必须的,如果不指定,则我们在python的交互模式下导入module_3.py这个模块时会报如下错误:

[python] view plaincopyprint?

  1. >>> from com.homer import module_3
  2. Traceback (most recent call last):
  3. File "<stdin>", line 1, in <module>
  4. ImportError: No module named pkg.module_3

因此,包目录下的__init__.py模块是必须的,但内容是可选的,可以为空内容,也可以写一些代码或作其他用途。PVM在导入某个包下的模块时会先导入这个包下的__init__.py模块,比如我们在__init__.py模块里添加内容:

  1. print("This is __init__ module")

然后,在交互模式下重新导入这个包,则输出效果如下:

[python] view plaincopyprint?

  1. >>> from com.homer import module_3
  2. This is __init__ module
  3. Hello World
  4. >>>

可见,PVM首先加载的是__init__.py模块,然后才是找该目录下的其他模块并进行加载。

python中的模块搜索路径

在一个模块被导入时,PVM会在后台从一系列路径中搜索该模块,其搜索过程如下:

1、在当前目录下搜索该模块;

2、在环境变量PYTHONPATH中指定的路径列表中依次搜索;

3、在python安装路径中搜索

事实上,PVM通过变量sys.path中包含的路径来搜索,这个变量里面包含的路径列表就是上面提到的这些路径信息,我们可以打印看下sys.pth都包含些哪些路径:

[python] view plaincopyprint?

  1. >>> import sys
  2. >>> print(sys.path)
  3. [‘‘, ‘C:\\Windows\\system32\\python33.zip‘, ‘F:\\Pro-files\\Python33\\DLLs‘, ‘F:\\Pro-files\\Python33\\lib‘, ‘F:\\Pro-files\\Python33‘, ‘F:\\Pro-files
  4. \\Python33\\lib\\site-packages‘]
  5. >>>

不同的机器上显示的路径信息可能不一样,但至少都包含上面提到的3点。知道了这个路径搜索规律后,我们就可以很方便的将某些目录动态的增加到搜索路径中去,比如在E盘下建立一个python模块module_4.py,内容如下:

[python] view plaincopyprint?

  1. # -*- coding:utf-8 -*-
  2. ‘‘‘‘‘pkg.module_4.py‘‘‘
  3. print("Hello world")
  4. print(2 ** 2)

然后在交互模式下执行导入:

[python] view plaincopyprint?

  1. >>> import module_4
  2. Traceback (most recent call last):
  3. File "<stdin>", line 1, in <module>
  4. ImportError: No module named module_4

报错是预料中的,因为F盘并不在python模块的搜索路径中,然后我们动态的增加这个路径到搜索模块中,再执行导入:

[python] view plaincopyprint?

  1. >>> import sys
  2. >>> sys.path.append("F:\Pro-files\workspace\myPython")
  3. >>> print(sys.path)
  4. [‘‘, ‘C:\\Windows\\system32\\python33.zip‘, ‘F:\\Pro-files\\Python33\\DLLs‘, ‘F:\\Pro-files\\Python33\\lib‘, ‘F:\\Pro-files\\Python33‘, ‘F:\\Pro-files
  5. \\Python33\\lib\\site-packages‘, ‘F:\\Pro-files\\workspace\\myPython‘]
  6. >>> from com.homer import module_4
  7. This is __init__ module
  8. Hello world
  9. 4
  10. >>>

首先是在sys.path中增加了F盘根目录作为搜索路径 sys.path.append("F:\Pro-files\workspace\myPython"),随后的打印中可以看到确实已经被添加到sys.path中去了,然后再执行导入就会正常导入模块并执行模块中的语句了。当然,我们通过交互模式新增加的搜索路径也仅仅是在当前交互模式下有效,一旦退出了那么就就失效了。因此,我们可以根据搜索路径规则的第2步中说的来设置PYTHONPATH环境变量就可以满足不同使用情况下都可以找到模块了。

from:http://blog.csdn.net/ithomer/article/details/17277833

时间: 2024-11-05 19:01:08

Python之模块和包学习的相关文章

selenium + python自动化测试unittest框架学习(四)python导入模块及包知识点

在写脚本的时候,发现导入某些模块,经常报错提示导入模块失败,这里来恶补下python导入模块的知识点. 1.模块导入时文件查找顺序 在脚本中,import xxx模块时的具体步骤: (1)新建一个module (2)将module插入到sys.module (3)查找module的路径,查找的顺序为先查找当前使用导入模块的文件同一级目录,之后是python的搜索模块的路径集sys.path,最后是python所添加的默认环境变量的路径Python path (4)module查找到之后装载mod

Python的模块与包如何使用?

本文和大家分享的主要是python模块与包相关内容,一起来看看吧,希望对大家学习python有所帮助. 一.Python 模块简介 在开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护. 为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少,很多编程语言都采用这种组织代码的方式.在 Python 中,一个 .py 文件就称之为一个模块(Module). 之前我们学习过函数,知道函数是实现一项或多项功能的一段程序 .其实模

python 深入模块和包

模块可以包含可执行语句以及函数的定义. 这些语句通常用于初始化模块. 它们只在 第一次 导入时执行.只在第一次导入的时候执行,第一次.妈蛋的第一次...后面再次导入就不执行了. [1](如果文件以脚本的方式执行,它们也会运行.) 每个模块都有自己的私有符号表, 模块内定义的所有函数用其作为全局符号表. 被导入的模块的名字放在导入模块的全局符号表中. import 语句的一个变体直接从被导入的模块中导入名字到导入模块的符号表中. 例如: >>> >>> from fibo

python之模块与包

一模块 二包 一模块 常见的场景:一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀. 但其实import加载的模块分为四个通用类别: 1 使用python编写的代码(.py文件) 2 已被编译为共享库或DLL的C或C++扩展 3 包好一组模块的包 4 使用C编写并链接到python解释器的内置模块 为什么要使用模块 如果你退出python解释器然后重新进入,那么你之前定义的函数或者变量都将丢失,因此我们通常将程序写到文件中以便永久保存下来,需要时就通过pyt

python基础---模块与包

1.模块导入方法 常见的场景: 一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀,导入模块可以实现功能的重复利用 import加载的模块分为四个通用类别: 1 使用python编写的代码(.py文件) 2 已被编译为共享库或DLL的C或C++扩展 3 包好一组模块的包 4 使用C编写并链接到python解释器的内置模块 a. import语句 python 内置了很多模块,比如os.sys.time等,也可以是自定义模块.模块包.C扩展等,使用import无

PYTHON常用模块和包

模块 '''模块:一系列功能的集合体?常见的四种模块:1.使用python编写的.py文件2.把一系列模块组织到一起的文件夹(注:文件夹下有一个__init__.py文件,该文件夹称之为包)3.使用C编写并链接到python解释器的内置模块4.已被编译为共享库或DLL的C或C++扩展''' 模块的搜索路径 '''搜索顺序:内存 => 内置模块 => sys.path?1.导入模块会优先在内存中查找2.内存中没有被加载的话,再去查找内置模块3.还没有查找到,就根据sys.path中的路径顺序逐一

第一篇:python的模块与包

模块的简介 模块就是一组功能的集合体,我们的程序可以导入模块来复用模块里的功能.每一个 Python 脚本.py文件都可以被当成是一个模块.模块以磁盘文件的形式存在.当一个模块变得过大,并且驱动了太多功能的话,就应该考虑拆一些代码出来另外建一个模块.模块里的代码可以是一段直接执行的脚本,也可以是一堆类似库函数的代码,从而可以被别的模块导 入(import)调用.模块可以包含直接运行的代码块.类定义. 函数定义或这几者的组合. 模块分类:Python标准库模块.Python第三方模块.应用程序自定

Python从零开始——模块与包

一:Python模块知识概览 二:Python模块的定义与引入 三:模块的搜素与命名空间 四:深入模块 五:模块管理——包的定义与引入 原文地址:https://www.cnblogs.com/ygj0930/p/11001315.html

【Python之模块及包的导入】

一.模块导入 1.定义 Python 模块(Module),是一个 Python 文件,以 .py 结尾,包含了 Python 对象定义和Python语句. 模块让你能够有逻辑地组织你的 Python 代码段. 把相关的代码分配到一个模块里能让你的代码更好用,更易懂. 模块能定义函数,类和变量,模块里也能包含可执行的代码. 包括:内置模块,自定义模块,第三方模块: 2.作用 最大的好处是大大提高了代码的可维护性.其次,编写代码不必从零开始.当一个模块编写完毕,就可以被其他地方引用.我们在编写程序