您的位置:首页 > 编程语言 > Python开发

简明Python教程学习笔记_3_模块

2016-03-21 22:46 681 查看

模块

如果你想要在其他程序中重用很多函数,那么你该如何编写程序呢?你可能已经猜到了,答案是使用模块。模块基本上就是一个包含了所有你定义的函数和变量的文件。为了在其他程序中重用模块,模块的文件名必须
.py
为扩展名。

python有三种导入模块的方法

其一,

import modname : 模块是指一个可以交互使用,或者从另一Python 程序访问的代码段。只要导入了一个模块,就可以引用它的任何公共的函数、类或属性。模块可以通过这种方法来使用其它模块的功能。

用import语句导入模块,就在当前的名称空间(namespace)建立了一个到该模块的引用.这种引用必须使用全称,也就是说,当使用在被导入模块中定义的函数时,必须包含模块的名字。所以不能只使用 funcname,而应该使用 modname.funcname

其二,

from modname import funcname

from modname import fa, fb, fc

或者 from modname import *

与第1种方法的区别:funcname 被直接导入到本地名字空间去了,所以它可以直接使用,而不需要加上模块名的限定

* 表示,该模块的所有公共对象(public objects)都被导入到 当前的名称空间,也就是任何只要不是以”_”开始的东西都会被导入。

modname没有被定义,所以modname.funcname这种方式不起作用。并且,如果funcname如果已经被定义,它会被新版本(该导入模块中的版本)所替代。如果funcname被改成指向其他对象,modname不能不会觉察到。

建议:

1)如果你要经常访问模块的属性和方法,且不想一遍又一遍地敲入模块名,使用 from module import

2)如果你想要有选择地导入某些属性和方法,而不想要其它的,使用 from module import

3)如果模块包含的属性和方法与你的某个模块同名,你必须使用import module来避免名字冲突

4)尽量少用 from module import * ,因为判定一个特殊的函数或属性是从哪来的有些困难,并且会造成调试和重构都更困难。

其三

内建函数__import__()

除了前面两种使用import关键字的方法以外,我们还可以使用内建函数 __import__() 来导入 module。两者的区别是,import 后面跟的必须是一个类型(type),而__import__() 的参数是一个字符串,这个字符串可能来自配置文件,也可能是某个表达式计算结果。例如

mymodule = __import__ (’module_name’)

附注:

1)模块的内容都放在一个模块文件中,如 mymodule 的内容应该放在PYTHONPATH 目录下的一个mymodule.py中,C实现的除外

2)包可以将几个模块名称空间组织起来, 如A.b 就表示在包A中的一个子模块b

可以单独导入某一个子模块,如Python文档中给出的例子

import sound.effects.echo

这样必须使用全称对里面的对象进行引用,如

sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)

还可以使用下面的语句来加载echo子模块

from Sound.Effects import echo

它在没有包前缀的情况下也可以使用, 所以它可以如下方式调用:

echo.echofilter(input, output, delay=0.7, atten=4)

不主张从一个包或模块中用import * 导入所有模块,因为这样的通常会导致可读性很差。

from Package import specific_submodule的用法并没有错,实际上这还是推荐的用法,除非导入的模块需要使用其它包中的同名子模块(the importing module needs to use submodules with the same name from different packages).

综上所述,一般情况应该使用import , 但有几个例外

1)module文档告诉你要用from-import的

2)导入一个包组件。需要一个包里面的某个子模块,一般用from A.b import c比import A.b.c 更方便 且不会冒混淆的危险.

使用模块

#!/usr/bin/python
# Filename: using_sys.py
import sys
print 'The command line arguments are:'
for i in sys.argv:
print i
print '\n\nThe PYTHONPATH is',sys.path,'\n'

在Python中用关键字import来引入某个模块,比如要引用模块math,就可以在文件最开始的地方用import math来引入。在调用math模块中的函数时,必须这样引用:

模块名.函数名

为什么必须加上模块名这样调用呢?因为可能存在这样一种情况:在多个模块中含有相同名称的函数,此时如果只是通过函数名来调用,解释器无法知道到底要调用哪个函数。所以如果像上述这样引入模块的时候,调用函数必须加上模块名。

import math

#这样会报错
print sqrt(2)

#这样才能正确输出结果
print math.sqrt(2)


有时候我们只需要用到模块中的某个函数,只需要引入该函数即可,此时可以通过语句

  from 模块名 import 函数名1,函数名2....
当然可以通过不仅仅可以引入函数,还可以引入一些常量。通过这种方式引入的时候,调用函数时只能给出函数名,不能给出模块名,但是当两个模块中含有相同名称函数的时候,后面一次引入会覆盖前一次引入。也就是说假如模块A中有函数function( ),在模块B中也有函数function( ),如果引入A中的function在先、B中的function在后,那么当调用function函数的时候,是去执行模块B中的function函数。
  如果想一次性引入math中所有的东西,还可以通过from math import *来实现,但是不建议这么做。

Python本身就内置了很多非常有用的模块,只要安装完毕,这些模块就可以立刻使用。以内建的sys模块为例,编写一个hello的模块:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

' a test module '

__author__ = 'author_name'

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()
使用sys模块的第一步,就是导入该模块:

import sys

导入sys模块后,我们就有了变量sys指向该模块,利用sys这个变量,就可以访问sys模块的所有功能。

sys模块有一个argv变量,用list存储了命令行的所有参数。argv至少有一个元素,因为第一个参数永远是该.py文件的名称,

例如:

运行python hello.py获得的sys.argv就是['hello.py'];

运行python hello.py 123abc获得的sys.argv就是['hello.py', '123abc']。

最后,注意到这两行代码:

if __name__=='__main__':
test()
当我们在命令行运行hello模块文件时,Python解释器把一个特殊变量__name__置为__main__。

而如果在其他地方导入该hello模块时,if判断将失败。

因此,这种if测试可以让一个模块通过命令行运行时执行一些额外的代码,最常见的就是运行测试。

一个模块顶层定义的变量,会自动变成模块的属性

data=[1,2,3]

def printme(var):
print var
if __name__ == '__main__':
printme(1)
data变量就是模块的一个属性。其实printme也是一个属性,只不过是一个函数罢了。

别名

导入模块时,还可以使用别名,这样,可以在运行时根据当前环境选择最合适的模块。

比如Python标准库一般会提供StringIO和cStringIO两个库,这两个库的接口和功能是一样的,但是cStringIO是C写的,速度更快,所以,你会经常看到这样的写法:

try:
import cStringIO as StringIO
except ImportError: # 导入失败会捕获到ImportError
import StringIO
这样就可以优先导入cStringIO。如果有些平台不提供cStringIO,还可以降级使用StringIO。导入cStringIO时,用import ... as ...指定了别名StringIO,因此,后续代码引用StringIO即可正常工作。

还有类似simplejson这样的库,在Python 2.6之前是独立的第三方库,从2.6开始内置,所以,会有这样的写法:

try:
import json # python >= 2.6
except ImportError:
import simplejson as json # python <= 2.5
由于Python是动态语言,函数签名一致接口就一样,因此,无论导入哪个模块后续代码都能正常工作。

作用域

在一个模块中,会定义很多函数和变量,但有的函数和变量希望给别人使用,有的函数和变量仅仅在模块内部使用。在Python中,是通过_前缀来实现的。

正常的函数和变量名是公开的(public),可以被直接引用,比如:abc,x123,PI等;

类似__xxx__这样的变量是特殊变量,可以被直接引用,但是有特殊用途,比如上面的__author__,__name__就是特殊变量,hello模块定义的文档注释也可以用特殊变量__doc__访问,我们自己的变量一般不要用这种变量名;

类似_xxx和__xxx这样的函数或变量就是非公开的(private),不应该被直接引用,比如_abc,__abc等;

之所以说,private函数和变量“不应该”被直接引用,而不是“不能”被直接引用,是因为Python并没有一种方法可以完全限制访问private函数或变量,但是,从编程习惯上不应该引用private函数或变量。

private函数或变量不应该被别人引用,那它们有什么用呢?请看例子:

def _private_1(name):
return 'Hello, %s' % name

def _private_2(name):
return 'Hi, %s' % name

def greeting(name):
if len(name) > 3:
return _private_1(name)
else:
return _private_2(name)
我们在模块里公开greeting()函数,而把内部逻辑用private函数隐藏起来了,这样,调用greeting()函数不用关心内部的private函数细节,这也是一种非常有用的代码封装和抽象的方法,即:外部不需要引用的函数全部定义成private,只有外部需要引用的函数才定义为public。

它如何工作

首先,我们利用
import
语句 输入
sys
模块。基本上,这句语句告诉Python,我们想要使用这个模块。
sys
模块包含了与Python解释器和它的环境有关的函数。

当Python执行
import sys
语句的时候,它在
sys.path
变量中所列目录中寻找
sys.py
模块。如果找到了这个文件,这个模块的主块中的语句将被运行,然后这个模块将能够被你使用 。注意,初始化过程仅在我们第一次 输入模块的时候进行。另外,“sys”是“system”的缩写。

sys
模块中的
argv
变量通过使用点号指明——
sys.argv
——这种方法的一个优势是这个名称不会与任何在你的程序中使用的
argv
变量冲突。另外,它也清晰地表明了这个名称是
sys
模块的一部分。

sys.argv
变量是一个字符串的 列表 (列表会在后面的章节详细解释)。特别地,
sys.argv
包含了命令行参数 的列表,即使用命令行传递给你的程序的参数。

如果你使用IDE编写运行这些程序,请在菜单里寻找一个指定程序的命令行参数的方法。

这里,当我们执行
python using_sys.py we are arguments
的时候,我们使用python命令运行
using_sys.py
模块,后面跟着的内容被作为参数传递给程序。Python为我们把它存储在
sys.argv
变量中。

记住,脚本的名称总是
sys.argv
列表的第一个参数。所以,在这里,
'using_sys.py'
sys.argv[0]
'we'
sys.argv[1]
'are'
sys.argv[2]
以及
'arguments'
sys.argv[3]
。注意,Python从0开始计数,而非从1开始。

sys.path
包含输入模块的目录名列表。我们可以观察到
sys.path
的第一个字符串是空的——这个空的字符串表示当前目录也是
sys.path
的一部分,这与
PYTHONPATH
环境变量是相同的。这意味着你可以直接输入位于当前目录的模块。否则,你得把你的模块放在
sys.path
所列的目录之一。

from..import语句

如果你想要直接输入
argv
变量到你的程序中(避免在每次使用它时打
sys.
),那么你可以使用
from sys import argv
语句。如果你想要输入所有
sys
模块使用的名字,那么可以使用
from sys import *
语句。这对于所有模块都适用。一般说来,避免使用
from..import
而使用
import
语句,因为这样可以使你的程序更加易读,也可以避免名称的冲突。

下面是一个使用
from..import
语法的版本。

#!/usr/bin/python
# Filename: mymodule_demo2.py

from mymodule import sayhi, version
# Alternative:
# from mymodule import *

sayhi()
print 'Version', version

命名空间和作用域

变量是拥有匹配对象的名字(标识符)。
命名空间是一个包含了变量名称们(键)和它们各自相应的对象们(值)的字典。

一个Python表达式可以访问局部命名空间和全局命名空间里的变量。同名隐藏的原则同C/C++
每个函数都有自己的命名空间。类的方法的作用域规则和通常函数的一样。默认任何在函数内赋值的变量都是局部的。因此,如果要给全局变量在一个函数里赋值,必须使用global语句。global VarName的表达式会告诉Python, VarName是一个全局变量,这样Python就不会在局部命名空间里寻找这个变量了。

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

Money = 2000
def AddMoney():
# 想改正代码就取消以下注释:
# global Money
Money = Money + 1
print Money
AddMoney()
print Money

globals()和locals()函数

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

模块的__name__

每个模块都有一个名称,在模块中可以通过语句来找出模块的名称。这在一个场合特别有用——就如前面所提到的,当一个模块被第一次输入的时候,这个模块的主块将被运行。假如我们只想在程序本身被使用的时候运行主块,而在它被别的模块输入的时候不运行主块,我们该怎么做呢?这可以通过模块的__name__属性完成。

#!/usr/bin/python
# Filename: using_name.py

if __name__ == '__main__':
print 'This program is being run by itself'
else:
print 'I am being imported from another module'

输出
$ python using_name.py
This program is being run by itself

$ python
>>> import using_name
I am being imported from another module
>>>
>>>print __name__
>>>__main__

它如何工作

每个Python模块都有它的
__name__
,如果它是
'__main__'
,这说明这个模块被用户单独运行,我们可以进行相应的恰当操作。

创建你自己的模块

#!/usr/bin/python
# Filename: mymodule.py
def sayhi():
print 'Hi, this is mymodule speaking.'
version = '0.1'
# End of mymodule.py

上面是一个 模块 的例子。你已经看到,它与我们普通的Python程序相比并没有什么特别之处。我们接下来将看看如何在我们别的Python程序中使用这个模块。

记住这个模块应该被放置在我们输入它的程序的同一个目录中,或者在
sys.path
所列目录之一。

#!/usr/bin/python
# Filename: mymodule_demo.py
import mymodule
mymodule.sayhi()
print 'Version', mymodule.version
输出
$ python mymodule_demo.py
Hi, this is mymodule speaking.
Version 0.1
在Python中,一个.py文件就称之为一个模块(Module)。模块的名字就是文件的名字。
  比如有这样一个文件test.py,在test.py中定义了函数add:

#test.py

def add(a,b):
return a+b
那么在其他文件中就可以先import test,然后通过test.add(a,b)来调用了,当然也可以通过from test import add来引入。
dir()函数

你可以使用内建的
dir
函数来列出模块定义的标识符。标识符有函数、类和变量。

当你为
dir()
提供一个模块名的时候,它返回模块定义的名称列表。如果不提供参数,它返回当前模块中定义的名称列表。

$ python
>>> import sys
>>> dir(sys) # get list of attributes for sys module
['__displayhook__', '__doc__', '__excepthook__', '__name__', '__stderr__',
'__stdin__', '__stdout__', '_getframe', 'api_version', 'argv',
'builtin_module_names', 'byteorder', 'call_tracing', 'callstats',
'copyright', 'displayhook', 'exc_clear', 'exc_info', 'exc_type',
'excepthook', 'exec_prefix', 'executable', 'exit', 'getcheckinterval',
'getdefaultencoding', 'getdlopenflags', 'getfilesystemencoding',
'getrecursionlimit', 'getrefcount', 'hexversion', 'maxint', 'maxunicode',
'meta_path','modules', 'path', 'path_hooks', 'path_importer_cache',
'platform', 'prefix', 'ps1', 'ps2', 'setcheckinterval', 'setdlopenflags',
'setprofile', 'setrecursionlimit', 'settrace', 'stderr', 'stdin', 'stdout',
'version', 'version_info', 'warnoptions']
>>> dir() # get list of attributes for current module
['__builtins__', '__doc__', '__name__', 'sys']
>>>
>>> a = 5 # create a new variable 'a'
>>> dir()
['__builtins__', '__doc__', '__name__', 'a', 'sys']
>>>
>>> del a # delete/remove a name
>>>
>>> dir()
['__builtins__', '__doc__', '__name__', 'sys']
>>>

它如何工作

首先,我们来看一下在输入的
sys
模块上使用
dir
。我们看到它包含一个庞大的属性列表。

接下来,我们不给
dir
函数传递参数而使用它——默认地,它返回当前模块的属性列表。注意,输入的模块同样是列表的一部分。

为了观察
dir
的作用,我们定义一个新的变量
a
并且给它赋一个值,然后检验
dir
,我们观察到在列表中增加了以上相同的值。我们使用
del
语句删除当前模块中的变量/属性,这个变化再一次反映在
dir
的输出中。

关于
del
的一点注释——这个语句在运行后被用来 删除 一个变量/名称。在这个例子中,
del a
,你将无法再使用变量
a
——它就好像从来没有存在过一样。

os和sys模块


sys模块

sys模块主要是用于提供对python解释器相关的操作


函数

sys.argv #命令行参数List,第一个元素是程序本身路径
sys.path #返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
sys.modules.keys() #返回所有已经导入的模块列表
sys.modules #返回系统导入的模块字段,key是模块名,value是模块
sys.exc_info() #获取当前正在处理的异常类,exc_type、exc_value、exc_traceback当前处理的异常详细信息
sys.exit(n) #退出程序,正常退出时exit(0)
sys.hexversion #获取Python解释程序的版本值,16进制格式如:0x020403F0
sys.version #获取Python解释程序的版本信息
sys.platform #返回操作系统平台名称
sys.maxint # 最大的Int值
sys.stdout #标准输出
sys.stdout.write('aaa') #标准输出内容
sys.stdout.writelines() #无换行输出
sys.stdin #标准输入
sys.stdin.read() #输入一行
sys.stderr #错误输出
sys.exc_clear() #用来清除当前线程所出现的当前的或最近的错误信息
sys.exec_prefix #返回平台独立的python文件安装的位置
sys.byteorder #本地字节规则的指示器,big-endian平台的值是'big',little-endian平台的值是'little'
sys.copyright #记录python版权相关的东西
sys.api_version #解释器的C的API版本
sys.version_info #'final'表示最终,也有'candidate'表示候选,表示版本级别,是否有后继的发行
sys.getdefaultencoding() #返回当前你所用的默认的字符编码格式
sys.getfilesystemencoding() #返回将Unicode文件名转换成系统文件名的编码的名字
sys.builtin_module_names #Python解释器导入的内建模块列表
sys.executable #Python解释程序路径
sys.getwindowsversion() #获取Windows的版本
sys.stdin.readline() #从标准输入读一行,sys.stdout.write(a) 屏幕输出a
sys.setdefaultencoding(name) #用来设置当前默认的字符编码(详细使用参考文档)
sys.displayhook(value) #如果value非空,这个函数会把他输出到sys.stdout(详细使用参考文档)
常用功能
sys.arg 获取位置参数
print(sys.argv)

执行该脚本,加参数的打印结果
python3 m_sys.py 1 2 3 4 5

['m_sys.py', '1', '2', '3', '4', '5']
可以发现 sys.arg返回的是整个位置参数,类似于shell的$0 $1...
sys.exit(n) 程序退出,n是退出是返回的对象
sys.version 获取python版本
>>> sys.version
'3.5.1 (v3.5.1:37a07cee5969, Dec 5 2015, 21:12:44) \n[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)]'
sys.path 返回模块的搜索路径列表,可通过添加自定义路径,来添加自定义模块
>>> sys.path
['', '/Library/Frameworks/Python.framework/Versions/3.5/lib/python35.zip', '/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5', '/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/plat-darwin', '/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/lib-dynload', '/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages']

sys.platform 返回当前系统平台 linux平台返回linux,windows平台返回win32,MAC返回darwin
>>> sys.platform
'darwin
sys.stdout.write() 输出内容
>>> sys.stdout.write('asd')
asd3
>>> sys.stdout.write('asd')
asd3
>>> sys.stdout.write('as')
as2


应用:

进度条:
#!/usr/bin/env python
# -*- coding: UTF-8 -*-

"""
sys 和python解析器相关
"""

from __future__ import division
import sys
import time

def view_bar(num, total):

rate = num / total
rate_num = int(rate * 100)
# r = '\r %d%%' %(rate_num)
r = '\r%s>%d%%' % ('=' * rate_num, rate_num,)
sys.stdout.write(r)
sys.stdout.flush

if __name__ == '__main__':
for i in range(0, 101):
time.sleep(0.1)
view_bar(i, 100)
效果:
====================================================================================================>100%



os模块

OS模块是Python标准库中的一个用于访问操作系统功能的模块,使用OS模块中提供的接口,可以实现跨平台访问


用于提供系统级别的操作

os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径
os.chdir(dirname) 改变当前脚本工作目录;相当于shell下cd
os.curdir 返回当前目录: ('.')
os.pardir 获取当前目录的父目录字符串名:('..')
os.makedirs('dir1/dir2') 可生成多层递归目录
os.removedirs('dirname1') 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
os.mkdir('dirname') 生成单级目录;相当于shell中mkdir dirname
os.rmdir('dirname') 删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
os.listdir('dirname') 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
os.remove() 删除一个文件
os.rename(oldname,new) 重命名文件/目录
os.stat('path/filename') 获取文件/目录信息
os.sep 操作系统特定的路径分隔符,win下为\,Linux下为/
os.linesep 当前平台使用的行终止符,win下为\t\n,Linux下为\n
os.pathsep 用于分割文件路径的字符串
os.name 字符串指示当前使用平台。win->'nt'; Linux->'posix'
os.system(bash command) 运行shell命令,直接显示
os.environ 获取系统环境变量
os.path.abspath(path) 返回path规范化的绝对路径
os.path.split(path) 将path分割成目录和文件名二元组返回
os.path.dirname(path) 返回path的目录。其实就是os.path.split(path)的第一个元素
os.path.basename(path) 返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素
os.path.exists(path) 如果path存在,返回True;如果path不存在,返回False
os.path.lexists #路径存在则返回True,路径损坏也返回True
os.path.isabs(path) 如果path是绝对路径,返回True
os.path.isfile(path) 如果path是一个存在的文件,返回True。否则返回False
os.path.isdir(path) 如果path是一个存在的目录,则返回True。否则返回False
os.path.join(path1[, path2[, ...]]) 将多个路径组合后返回,第一个绝对路径之前的参数将被忽略
os.path.getatime(path) 返回path所指向的文件或者目录的最后存取时间
os.path.getmtime(path) 返回path所指向的文件或者目录的最后修改时间
os.path.commonprefix(list) #返回list(多个路径)中,所有path共有的最长的路径。
os.path.expanduser(path) #把path中包含的"~"和"~user"转换成用户目录
os.path.expandvars(path) #根据环境变量的值替换path中包含的”$name”和”${name}”
os.access('pathfile',os.W_OK) 检验文件权限模式,输出True,False
os.chmod('pathfile',os.W_OK) 改变文件权限模式

如果不同的人编写的模块名相同怎么办?为了避免模块名冲突,Python又引入了按目录来组织模块的方法,称为包(Package)。

举个例子,一个abc.py的文件就是一个名字叫abc的模块,一个xyz.py的文件就是一个名字叫xyz的模块。

假设abc和xyz这两个模块名字与其他模块冲突了,可以通过包来组织模块,避免冲突。方法是选择一个顶层包名,比如mycompany,按照如下目录存放:



引入了包以后,只要顶层的包名不与别人冲突,那所有模块都不会与别人冲突。

现在,abc.py模块的名字就变成了mycompany.abc,类似的,xyz.py的模块名变成了mycompany.xyz。

请注意,每一个包目录下面都会有一个__init__.py的文件,这个文件是必须存在的,否则,Python就把这个目录当成普通目录,而不是一个包。

__init__.py可以是空文件,也可以有Python代码,因为__init__.py本身就是一个模块,而它的模块名就是mycompany。

类似的,可以有多级目录,组成多级层次的包结构。比如如下的目录结构:



文件www.py的模块名就是mycompany.web.www,两个文件utils.py的模块名分别是mycompany.utils和mycompany.web.utils。

mycompany.web也是一个模块,请指出该模块对应的.py文件。

安装第三方模块

在Python中,安装第三方模块,是通过setuptools这个工具完成的。Python有两个封装了setuptools的包管理工具:easy_install和pip。目前官方推荐使用pip。

强烈推荐安装 pip 安装 python 第三方模块

安装一个第三方库——Python Imaging Library,这是Python下非常强大的处理图像的工具库。

一般来说,第三方库都会在Python官方的网站pypi.python.org注册,要安装一个第三方库,必须先知道该库的名称,可以在官网或者pypi上搜索,比如Python Imaging Library的名称叫PIL,因此,安装Python Imaging Library的命令就是:pip install PIL

有了PIL,处理图片易如反掌。随便找个图片生成缩略图:

>>> import Image
>>> im = Image.open('test.png')
>>> print im.format, im.size, im.mode
PNG (400, 300) RGB
>>> im.thumbnail((200, 100))
>>> im.save('thumb.jpg', 'JPEG')
模块搜索路径
默认情况下,Python解释器会搜索当前目录、所有已安装的内置模块和第三方模块,搜索路径存放在sys模块的path变量中:

>>> import sys
>>> sys.path
['', '/Library/Python/2.7/site-packages/pycrypto-2.6.1-py2.7-macosx-10.9-intel.egg', '/Library/Python/2.7/site-packages/PIL-1.1.7-py2.7-macosx-10.9-intel.egg', ...]
如果要添加自己的搜索目录,有两种方法:

一是直接修改sys.path,添加要搜索的目录:

>>> import sys
>>> sys.path.append('/Users/michael/my_py_scripts')
这种方法是在运行时修改,运行结束后失效。

第二种方法是设置环境变量PYTHONPATH,该环境变量的内容会被自动添加到模块搜索路径中。设置方式与设置Path环境变量类似。注意只需要添加你自己的搜索路径,Python自己本身的搜索路径不受影响。

使用__future__

Python每个新版本都会增加一些新功能,或对原来功能作一些改动。有些改动是不兼容旧版本的,即在当前版本运行正常的代码,到下一个版本运行就可能不正常。

从Python 2.7到Python 3.x就有不兼容的一些改动,比如2.x里的字符串用'xxx'表示str,Unicode字符串用u'xxx'表示unicode,而在3.x中,所有字符串都被视为unicode,因此,写u'xxx'和'xxx'是完全一致的,而在2.x中以'xxx'表示的str就必须写成b'xxx',以此表示“二进制字符串”。

要直接把代码升级到3.x是比较冒进的,因为有大量的改动需要测试。相反,可以在2.7版本中先在一部分代码中测试一些3.x的特性,如果没有问题,再移植到3.x不迟。

Python提供了__future__模块,把下一个新版本的特性导入到当前版本,于是我们就可以在当前版本中测试一些新版本的特性。举例说明如下:

为了适应Python 3.x的新的字符串的表示方法,在2.7版本的代码中,可以通过unicode_literals来使用Python 3.x的新的语法:

# still running on Python 2.7

from __future__ import unicode_literals

print '\'xxx\' is unicode?', isinstance('xxx', unicode)
print 'u\'xxx\' is unicode?', isinstance(u'xxx', unicode)
print '\'xxx\' is str?', isinstance('xxx', str)
print 'b\'xxx\' is str?', isinstance(b'xxx', str)
注意到上面的代码仍然在Python 2.7下运行,但结果显示去掉前缀u的'a string'仍是一个unicode,而加上前缀b的b'a string'才变成了str:
$ python task.py
'xxx' is unicode? True
u'xxx' is unicode? True
'xxx' is str? False
b'xxx' is str? True
类似的情况还有除法运算。在Python 2.x中,对于除法有两种情况,如果是整数相除,结果仍是整数,余数会被扔掉,这种除法叫“地板除”:
>>> 10 / 3
3
要做精确除法,必须把其中一个数变成浮点数:
>>> 10.0 / 3
3.3333333333333335
而在Python 3.x中,所有的除法都是精确除法,地板除用//表示:
$ python3
Python 3.3.2 (default, Jan 22 2014, 09:54:40)
[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.2.79)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 10 / 3 3.3333333333333335
>>> 10 // 3
3
如果你想在Python 2.7的代码中直接使用Python 3.x的除法,可以通过__future__模块的division实现:
from __future__ import division

print '10 / 3 =', 10 / 3
print '10.0 / 3 =', 10.0 / 3
print '10 // 3 =', 10 // 3

结果如下:
10 / 3 = 3.33333333333
10.0 / 3 = 3.33333333333
10 // 3 = 3


由于Python是由社区推动的开源并且免费的开发语言,不受商业公司控制,因此,Python的改进往往比较激进,不兼容的情况时有发生。Python为了确保你能顺利过渡到新版本,特别提供了__future__模块,让你在旧的版本中试验新版本的一些特性。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: