本节开始学习模块的相关知识,主要包括模块的编译,模块的搜索路径、包等知识


1.模块


如果我们直接在解释器中编写python,当我们关掉解释器后,再进去。我们之前编写的代码都丢失了。因此,我们需要将我们编写的代码保存在文件中,这样我们就可以以脚本的形式多次运行它。 每一个包含Python语句并且扩展名为.py的文件就是一个模块,模块的名字就是文件名的名字(不包含扩展名)。例如,我们创建一个文件:addab.py ,文件中的代码如下:

def  testAdd(a,b):
print a+b #打印a+b的值

我们打开解释器,导入addab模块,就可以调用该模块中的testAdd方法了

>>> import addab
>>> addab.testAdd(1,2)
3

我们可以通过__name__来查看模块的名字,__name__是一个字符型的全局变量

>>> import addab
>>> addab.__name__
'addab'

如果你经常使用一个模块中的某个函数,你可以将它赋值给一个局部变量

>>> import addab
>>> add=addab.testAdd
>>> add(1,2)
3

2.模块的导入

我们在运行一个模块的时候,可能会用到其他模块,这时候,我们就需要在该模块中导入其他模块,我们可以使用 import module 或者from module import ..的方式来导入模块。 例如,我们再创建另一个名为:maintest.py的文件,该文件需要用到addab模块,文件中的代码如下:

#_*_coding=utf-8 _*_
import addab
def testAddab(x,y):
addab.testAdd(x,y) # 调用addab模块中的函数 if __name__=="__main__":
testAddab(10,20)

运行maintest.py ,结果如下:

>>>
30

我们还可以使用from module import ..的形式导入模块,因此我们可以修改maintest.py为如下形式:

#_*_coding=utf-8 _*_
from addab import testAdd
def testAddab(x,y):
testAdd(x,y) # 调用addab模块中的函数 if __name__=="__main__":
testAddab(10,20)

除此之外,我们还可以使用 from module import * 的形式,该形式的意思是导入module下的所有内容,包括函数、变量或类

#_*_coding=utf-8 _*_
from addab import *
def testAddab(x,y):
testAdd(x,y) # 调用addab模块中的函数 if __name__=="__main__":
testAddab(10,20)

注意:maintest.py 的代码 :if __name__=="__main__" 的意思是判断maintest模块是直接运行的,还是被import 运行的,只有直接运行该模块,if块中的代码才会被执行。

如果是直接运行的,那么__name__ =="__main__"

如果是被导入运行的,那么__name__=="maintest"

例如,我们更改maintest.py 为如下内容:

#_*_coding=utf-8 _*_
from addab import *
def testAddab(x,y):
testAdd(x,y) # 调用addab模块中的函数 print __name__ #打印name的值 if __name__=="__main__":
testAddab(10,20) else:
print ' imported'

我们直接运行该模块,运行结果如下:

D:pythonstudy\test>python maintest.py
__main__
30

我们通过导入该模块,运行结果如下:

>>> import maintest
maintest
imported

3.模块路径搜索


当模块被导入的时候,解释器会首先在内建模块中搜索该模块,如果没有找到,会从sys.path包含的路径中查找该模块。 我们通过几个例子来说明模块路径的搜索过程

例子1:当模块被导入的时候,解释器会首先在内建模块中搜索该模块,如果没有找到,再从sys.path包含的路径中查找模块

我们的python安装在d盘的目录下,首先来查看一下sys.path:

>>> import sys
>>> sys.path
['', 'D:\\python2.7\\Lib\\idlelib', 'D:\\python2.7\\lib\\site-packages\\robotframework_selenium2library-1.6.0-py2.7.egg', 'D:\\python2.7\\lib\\site-packages\\docutils-0.12-py2.7.egg', 'D:\\python2.7\\lib\\site-packages\\selenium-2.44.0-py2.7.egg', 'D:\\python2.7\\lib\\site-packages\\decorator-3.4.0-py2.7.egg', 'D:\\python2.7\\lib\\site-packages\\pymysql-0.6.2-py2.7.egg', 'D:\\python2.7\\lib\\site-packages\\pip_tools-0.3.5-py2.7.egg', 'D:\\python2.7\\lib\\site-packages\\robotframework_sshlibrary-2.1.1-py2.7.egg', 'D:\\python2.7\\lib\\site-packages\\paramiko-1.15.1-py2.7.egg', 'D:\\python2.7\\lib\\site-packages\\ecdsa-0.11-py2.7.egg', 'C:\\windows\\system32\\python27.zip', 'D:\\python2.7\\DLLs', 'D:\\python2.7\\lib', 'D:\\python2.7\\lib\\plat-win', 'D:\\python2.7\\lib\\lib-tk', 'D:\\python2.7', 'D:\\python2.7\\lib\\site-packages', 'D:\\python2.7\\lib\\site-packages\\wx-2.8-msw-unicode']

下面我在目录(该目录不在sys.path中)C:\Users\PC\Desktop\pythonstudy\test2下,创建一个自定义模块module.py,内容如下:

#_*_coding=utf-8 _*_
def testModuleSeachPath():
print "this is test2" testModuleSeachPath()

我们直接在python shell中import 该模块,会提示找不到该模块,原因就是该模块不是内建模块,也不在sys.path中,所以找不到:

>>> import Module

Traceback (most recent call last):
File "<pyshell#2>", line 1, in <module>
import Module
ImportError: No module named Module

我们手动将Module.py所在的目录加入sys.path 中,再导入该模块,看看解释器是否能找到该模块呢?

>>> sys.path.append("C:\\Users\\PC\Desktop\\pythonstudy\\test2")
>>> sys.path
['', 'D:\\python2.7\\Lib\\idlelib', 'D:\\python2.7\\lib\\site-packages\\robotframework_selenium2library-1.6.0-py2.7.egg', 'D:\\python2.7\\lib\\site-packages\\docutils-0.12-py2.7.egg', 'D:\\python2.7\\lib\\site-packages\\selenium-2.44.0-py2.7.egg', 'D:\\python2.7\\lib\\site-packages\\decorator-3.4.0-py2.7.egg', 'D:\\python2.7\\lib\\site-packages\\pymysql-0.6.2-py2.7.egg', 'D:\\python2.7\\lib\\site-packages\\pip_tools-0.3.5-py2.7.egg', 'D:\\python2.7\\lib\\site-packages\\robotframework_sshlibrary-2.1.1-py2.7.egg', 'D:\\python2.7\\lib\\site-packages\\paramiko-1.15.1-py2.7.egg', 'D:\\python2.7\\lib\\site-packages\\ecdsa-0.11-py2.7.egg', 'C:\\windows\\system32\\python27.zip', 'D:\\python2.7\\DLLs', 'D:\\python2.7\\lib', 'D:\\python2.7\\lib\\plat-win', 'D:\\python2.7\\lib\\lib-tk', 'D:\\python2.7', 'D:\\python2.7\\lib\\site-packages', 'D:\\python2.7\\lib\\site-packages\\wx-2.8-msw-unicode', 'C:\\Users\\PC\\Desktop\\pythonstudy\\test2']
>>> import Module
this is test2

这时候,导入模块成功了,说明模块在搜索的过程中查找了sys.path

例子2:假如我们在两个目录中都定义了Module.py ,并且两个目录都在sys.path中,这时候,导入模块,sys.path靠前目录中的模块会优先被执行。

我们在目录C:\Users\PC\Desktop\pythonstudy\test下再定义一个Module.py,内容如下:

#_*_coding=utf-8 _*_
def testModuleSeachPath():
print "this is test1" testModuleSeachPath()

我们再将C:\Users\PC\Desktop\pythonstudy\test目录加入到sys.path中,这个时候再import Module,会不会报错呢?:

>>> sys.path.append("C:\\Users\\PC\\Desktop\\pythonstudy\\test")
>>> sys.path
['', 'D:\\python2.7\\Lib\\idlelib', 'D:\\python2.7\\lib\\site-packages\\robotframework_selenium2library-1.6.0-py2.7.egg', 'D:\\python2.7\\lib\\site-packages\\docutils-0.12-py2.7.egg', 'D:\\python2.7\\lib\\site-packages\\selenium-2.44.0-py2.7.egg', 'D:\\python2.7\\lib\\site-packages\\decorator-3.4.0-py2.7.egg', 'D:\\python2.7\\lib\\site-packages\\pymysql-0.6.2-py2.7.egg', 'D:\\python2.7\\lib\\site-packages\\pip_tools-0.3.5-py2.7.egg', 'D:\\python2.7\\lib\\site-packages\\robotframework_sshlibrary-2.1.1-py2.7.egg', 'D:\\python2.7\\lib\\site-packages\\paramiko-1.15.1-py2.7.egg', 'D:\\python2.7\\lib\\site-packages\\ecdsa-0.11-py2.7.egg', 'C:\\windows\\system32\\python27.zip', 'D:\\python2.7\\DLLs', 'D:\\python2.7\\lib', 'D:\\python2.7\\lib\\plat-win', 'D:\\python2.7\\lib\\lib-tk', 'D:\\python2.7', 'D:\\python2.7\\lib\\site-packages', 'D:\\python2.7\\lib\\site-packages\\wx-2.8-msw-unicode', 'C:\\Users\\PC\\Desktop\\pythonstudy\test2', 'C:\\Users\\PC\\Desktop\\pythonstudy\\test2', 'C:\\Users\\PC\\Desktop\\pythonstudy\\test']
>>> import Module
>>>

这时候,我们发现没有报错,但是模块也没有被直接执行。 但是我们再输入Module.testModuleSeachPath()的话,可以看到:

>>> Module.testModuleSeachPath()
this is test2

这说明目录test2中的'C:\\Users\\PC\\Desktop\\pythonstudy\\test2'的模块被执行了。

例子3:创建一个和内建模块名称一样的模块,并将该目录加入sys.path,再import该模块

我们在C:\Users\PC\Desktop\pythonstudy\test2目录下创建一个名为sys.py的模块,内容如下:

def testSysModule():
print "test sys Module"
testSysModule()

我们再尝试导入sys模块,并调用我们自己定义的方法:testSysModule()

>>> import sys

>>> sys.path
['', 'D:\\python2.7\\Lib\\idlelib', 'D:\\python2.7\\lib\\site-packages\\robotframework_selenium2library-1.6.0-py2.7.egg', 'D:\\python2.7\\lib\\site-packages\\docutils-0.12-py2.7.egg', 'D:\\python2.7\\lib\\site-packages\\selenium-2.44.0-py2.7.egg', 'D:\\python2.7\\lib\\site-packages\\decorator-3.4.0-py2.7.egg', 'D:\\python2.7\\lib\\site-packages\\pymysql-0.6.2-py2.7.egg', 'D:\\python2.7\\lib\\site-packages\\pip_tools-0.3.5-py2.7.egg', 'D:\\python2.7\\lib\\site-packages\\robotframework_sshlibrary-2.1.1-py2.7.egg', 'D:\\python2.7\\lib\\site-packages\\paramiko-1.15.1-py2.7.egg', 'D:\\python2.7\\lib\\site-packages\\ecdsa-0.11-py2.7.egg', 'C:\\windows\\system32\\python27.zip', 'D:\\python2.7\\DLLs', 'D:\\python2.7\\lib', 'D:\\python2.7\\lib\\plat-win', 'D:\\python2.7\\lib\\lib-tk', 'D:\\python2.7', 'D:\\python2.7\\lib\\site-packages', 'D:\\python2.7\\lib\\site-packages\\wx-2.8-msw-unicode', 'C:\\Users\\PC\\Desktop\\pythonstudy\\test2', 'C:\\Users\\PC\\Desktop\\pythonstudy\\test']

>>> sys.testSysModule()

Traceback (most recent call last):
File "<pyshell#1>", line 1, in <module>
sys.testSysModule()
AttributeError: 'module' object has no attribute 'testSysModule'

我们发现我们自己定义的模块并没有被搜索到,而是运行了python自带的模块sys。 因此我们在命名自己创建的模块时,不要与Python自带的模块相冲突


4.编译python文件


我们可以将python编译成.pyc、.pyo形式

python 具有自带的编译器py_compile ,我们可以用以下方式编译.py文件:

python -m py_compile Module.py 编译后,会在Module.py所在目录下出现Module.pyc

python -O py_compile Module.py 编译后,会在Module.py所在目录下出现Module.pyo

python -OO py_compile Module.py 编译后,会在Module.py所在目录下出现Module.pyo

注:参数 -O和-OO的区别在于:它们都对代码进行了一定的优化。 但是-O 去掉了代码中的assert语句,-OO 去掉了代码中的__doc__字符串

.pyc、.pyo文件有如下特点:

  • 直接运行.pyc、.pyo并不会提高项目的运行速度,只会提高文件的载入速度
  • 隐藏了源代码,它们很难被反编译
  • 它们是跨平台的字节码文件,可以不需要.py的文件,就可以直接运行

5.包(packages)


python中也有包的概念。在大型开发项目中,可能有多个开发人员在共同编写代码,在这种情况下,可能会出现模块命名或者变量名重复的情况。 这样我们就需要命名空间来组织每个开发者编写的模块,或者将功能相近的模块放在同一个文件夹下,我们可以将不同的文件夹看成是一个包。 不同的是当我们将文件夹看成包后,该文件夹下必须要有一个__init__.py 文件(该文件可以什么都不写),例如:

test/
__init__.py
pakage1/
__init__.py
module1.py
module2.py pakage2/
__init__.py
module1.py
module2.py

我们想使用pakage1下的module1.py 可以这样使用:import test.pakage1.module1

注意:使用from package import item  ,item可以是一个子包或一个模块,或方法、类、变量

使用import item.subitem.subsubitem  ,subsubitem可以是一个模块或一个子包,但是不能是一个方法、类或变量

(Python )模块、包的更多相关文章

  1. (转载)Linux平台下安装 python 模块包

    https://blog.csdn.net/aiwangtingyun/article/details/79121145 一.安装Python Windows平台下: 进入Python官网下载页面下载 ...

  2. 羞羞的Python模块包

    目录 一.pip 二.pip常用命令 三.No module 'xxxxx' 四.写在最后   前言 写Python代码的时候,经常会遇到包的问题,但是都是遇到一次,搜索一次,解决了.下一次还是同样的 ...

  3. Python模块包(pycharm右键创建文件夹和python package的区别)中__init__.py文件的作用

    在eclipse中用pydev开发Python脚本时,我遇到了一个这样的现象,当我新建一个pydev package时,总会自动地生成一个空的__init__.py文件,因为是python新手,所以很 ...

  4. python模块, 包的初识

    Python 模块(Module), 是一个 Python 文件,以 .py 结尾,包含了 Python 对象定义和Python语句. 模块让你能够有逻辑地组织你的 Python 代码段. 把相关的代 ...

  5. 18.Python模块包(pycharm右键创建文件夹和python package的区别)中__init__.py文件的作用

    原来在python模块的每一个包中,都有一个__init__.py文件(这个文件定义了包的属性和方法)然后是一些模块文件和子目录,假如子目录中也有 __init__.py 那么它就是这个包的子包了.当 ...

  6. Python模块/包/库安装几种方法(转载)

    一.方法1: 单文件模块直接把文件拷贝到 $python_dir/Lib 二.方法2: 多文件模块,带setup.py 下载模块包(压缩文件zip或tar.gz),进行解压,CMD->cd进入模 ...

  7. Python——模块&包&异常

    模块&包&异常 一. 模块 Python 模块(Module),是一个 Python 文件,以 .py 结尾,包含了 Python 对象定义(变量)和Python语句. 模块能定义函数 ...

  8. Python模块包中__init__.py文件的作用

    转载自:http://hi.baidu.com/tjuer/item/ba37ac4ce7482a0f6dc2f08b 模块包: 包通常总是一个目录,目录下为首的一个文件便是 __init__.py. ...

  9. python模块与包的导入

    1. 模块与包的区别 模块,即module,一个包含python语句的.py文件就是一个模块!每个源代码文件都会自动成为模块!没有额外的语法用来声明模块. 包,又称模块包,即module packag ...

  10. Python札记 -- 使用easy_install进行模块/包管理

    今天在阅读以前项目代码时,发现里面使用的第三方模块的参数相当诡异,总是对不上.经过分析之后,发现是自己安装的第三方模块跟项目使用的版本不一致.在Python中进行模块/包管理的话,就不得不提到easy ...

随机推荐

  1. Unity3D 双摇杆 c# JoyStick 实现自己的双摇杆

    转载请声明: http://www.cnblogs.com/ADaii/p/3859520.html Untiy3D 官方摇杆脚本只能完成一个摇杆,要实现双摇杆比较费劲 现在我吧我废了一通宵的结果共享 ...

  2. java 获取classpath下文件多种方式

    java 获取classpath下文件多种方式 一:properties下配置 在resources下定义server.properties register.jks.path=classpath\: ...

  3. linux 源码安装

    下载源码安装包,一般为.tar.gz格式 解压源码至文件夹,linux终端进入该文件夹,安装只需三步,第四步为扫尾工作: ./configure --prefix=/usr/self/文件夹名称    ...

  4. 洛谷P3374 【模板】树状数组 1

    P3374 [模板]树状数组 1 140通过 232提交 题目提供者HansBug 标签 难度普及/提高- 提交  讨论  题解 最新讨论 题目描述有误 题目描述 如题,已知一个数列,你需要进行下面两 ...

  5. (Forward) Music Player: From UI Proposal to Code

    Some developers have difficult to code when the UI proposal is a bit “sophisticated” or “complex”. M ...

  6. Spring:No bean named 'beanScope' is defined

    初学Spring,“No bean named 'beanScope' is defined”这个问题困扰了我好几个小时,查资料无果后,重写好几遍代码后发现问题居然是配置文件不能放在包里...要放在s ...

  7. 2016-06-06:X264码率控制

    H.264与x264 H264是一个视频压缩编码标准.https://zh.wikipedia.org/wiki/H.264/MPEG-4_AVC X264实现H264视频压缩标准的开源项目.http ...

  8. mac配置nginx

    基本的安装其实网上一大半教程:      安装:brew install nginx  配置注意要点:      1.主要配置监听的端口和php-fpm监听的端口相同可以配置成默认的:(127.0.0 ...

  9. 26、首先通过javascript包的异步加载来学习echarts包的结构

    1.在这里先写一写前言,今天在公司搞定了一个对于滚动条进行定位的case,明天开始做TestManagement. 首先大家先来一起看一看流行的javascript文件的加载方式,这里采用别人博客上的 ...

  10. dubbo properties

    DUBBO配置项的优先级: java -D优先于 Spring配置,Spring配置优先于 properties文件的配置,这也符合一般项目的规则. 覆盖策略: JVM启动-D参数优先,这样可以使用户 ...