Python学习笔记 (第10课)

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



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可以是一个模块或一个子包,但是不能是一个方法、类或变量

时间: 2024-10-20 06:30:25

Python学习笔记 (第10课)的相关文章

Python学习笔记__12.10章 XML

# 这是学习廖雪峰老师python教程的学习笔记 1.概览 XML虽然比JSON复杂,在Web中应用也不如以前多了,不过仍有很多地方在用,所以,有必要了解如何操作XML. 1.DOM vs SAX 操作XML有两种方法:DOM和SAX.DOM会把整个XML读入内存,解析为树,因此占用内存大,解析慢,优点是可以任意遍历树的节点.SAX是流模式,边读边解析,占用内存小,解析快,缺点是我们需要自己处理事件. 正常情况下,优先考虑SAX,因为DOM实在太占内存. 2.使用SAX解析XML 在Python

python 学习笔记(10)

字符串方法 find  join    lower    replace    split    strip    translate find: 可以在一个较长的字符串中查找字符串,返回值是这个字符串所在的位置的最左端索引,找不到返回 -1 例: >>>'With a moo-moo here,and a moo-moo there'.find('moo') 7 >>> 'With a moo-moo here,and a moo-moo there'.find('h

python学习笔记(10)-python第一个小程序hello world

本节点标题1.第一个小程序hello world1.1.python2与python3的hello world1.2.换行的打印 =======================================================================================================================1.第一个小程序hello world1.1.python2与python3的hello world>>> print &q

Python学习笔记 (第8课)

本节我们将学习python的另一种数据类型:集合(set) 1.集合(set) 集合在Python中是一种没有重复元素,且无序的数据类型,且不能通过索引来引用集合中的元素 >>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana'] >>> set(basket) set(['orange', 'pear', 'apple', 'banana']) set1-set2来获得在set1中的元素在

OpenCV之Python学习笔记

OpenCV之Python学习笔记 直都在用Python+OpenCV做一些算法的原型.本来想留下发布一些文章的,可是整理一下就有点无奈了,都是写零散不成系统的小片段.现在看 到一本国外的新书<OpenCV Computer Vision with Python>,于是就看一遍,顺便把自己掌握的东西整合一下,写成学习笔记了.更需要的朋友参考. 阅读须知: 本文不是纯粹的译文,只是比较贴近原文的笔记:         请设法购买到出版社出版的书,支持正版. 从书名就能看出来本书是介绍在Pytho

Python学习笔记_Python对象

Python学习笔记_Python对象 Python对象 标准类型 其他内建类型 类型对象和type类型对象 Python的Null对象None 标准类型操作符 对象值的比较 对象身份比较 布尔类型 标准类型的内建函数 typeObj cmpobj1 obj2 strobj reprobj typeobj isinstanceobj 标准类型的分类 存储模型 更新模型 访问模型 不支持的类型 Python学习笔记_Python对象 首先来理解一个通俗的含义,什么是对象?其实对象无论在什么语言里面

OpenCV for Python 学习笔记 三

给源图像增加边界 cv2.copyMakeBorder(src,top, bottom, left, right ,borderType,value) src:源图像 top,bottem,left,right: 分别表示四个方向上边界的长度 borderType: 边界的类型 有以下几种: BORDER_REFLICATE # 直接用边界的颜色填充, aaaaaa | abcdefg | gggg BORDER_REFLECT # 倒映,abcdefg | gfedcbamn | nmabcd

python 学习笔记 14 -- 常用的时间模块之datetime

书接上文,前面我们讲到<常用的时间模块之time>,这次我们学习datetime -- 日期和时间值管理模块 使用apihelper 查看datetime 模块,我们可以看到简单的几项: date       ---  日期对象,结构为date(year, month, day) time       ---  时间值对象,结构为 time([hour[, minute[, second[, microsecond[, tzinfo]]]]]).时间对象所有的参数都是可选的.tzinfo 可以

【python学习笔记】6.抽象

[python学习笔记]6.抽象 创建函数: 使用def语句定义函数,不用声明参数类型,和返回值类型 def function_name(param1, param2): 'this is document' pass # fuction body return value # 可选 函数体的第一行字符串被用作文档字符串 callable(func): 用来判读func是否可以调用 help函数用来返回相关函数的文档 函数名可以作为变量赋值一个变量 位置参数:函数调用期间,参数按照参数列表中的顺

python学习笔记[3]-邮件的发送

本文摘抄自:http://www.cnblogs.com/xiaowuyi/archive/2012/03/17/2404015.html 一.相关模块介绍 发送邮件主要用到了smtplib和email两个模块,这里首先就两个模块进行一下简单的介绍:    1.smtplib模块 smtplib.SMTP([host[, port[, local_hostname[, timeout]]]])   SMTP类构造函数,表示与SMTP服务器之间的连接,通过这个连接可以向smtp服务器发送指令,执行