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

模块

如果你想要在其他程序中重用很多函数,那么你该如何编写程序呢?你可能已经猜到了,答案是使用模块。模块基本上就是一个包含了所有你定义的函数和变量的文件。为了在其他程序中重用模块,模块的文件名必须.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 sysdef test():args = sys.argvif 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: # 导入失败会捕获到ImportErrorimport 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' % namedef _private_2(name):return 'Hi, %s' % namedef 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.pyfrom 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 MoneyMoney = Money + 1
print Money
AddMoney()
print Money

globals()和locals()函数

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

模块的__name__

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

#!/usr/bin/python
# Filename: using_name.pyif __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.pydef 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.7from __future__ import unicode_literalsprint '\'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 divisionprint '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__模块,让你在旧的版本中试验新版本的一些特性。



本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/497253.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python: 使用socket实现局域网不同主机通信。解决ConnectionResetError: [WinError 10054] 远程主机强迫关闭了一个现有的连接。

目录1 socket的使用1.1 TCP方法1.2 UDP方法2 局域网内连接2.1总结1 socket的使用 1.1 TCP方法 在socket中使用socket.socket建立会话&#xff0c;如果是服务器&#xff0c;需要绑定服务器地址和端口号&#xff0c;然后进行循环监听&#xff0c;当有客户端连接时再接收数据。 …

德勤:2018年科技、传媒和电信行业未来趋势预测

来源&#xff1a;亿欧近日&#xff0c;德勤发布了《2018科技、传媒和电信行业预测》报告&#xff0c;对世界与中国的科技、传媒和电信行业在未来1-5年的趋势进行了预测。该报告通过与世界各国行业主管和评论家的数百场访谈及对世界各地数万名消费者进行的调查&#xff0c;分析了…

python: SHA256算法的实现和消息的哈希散列值计算

目录1 SHA2562 实现原理2.1 消息预处理2.2 使用的常量和循环移位函数2.3 主循环3 结果4 对中文编码1 SHA256 SHA256是SHA-2下的一个子算法&#xff0c;与之类似的还有SHA224、SHA384、SHA512&#xff0c;算法原理基本一致。 哈希算法通过对消息进行计算&#xff0c;生成一定长…

财报上的云计算战场: 巨头们垄断加剧

来源&#xff1a; 第一财经一周之内&#xff0c;四大云业务巨头公司前后脚发布财报。亚马逊的云业务&#xff08;AWS&#xff09;依然跑在了最前面&#xff0c;以174亿美元排在首位。微软、谷歌、阿里巴巴也没有放慢步伐。阿里云去年累计的营收超过了百亿&#xff1b;微软的Azu…

python实现RSA算法,对数据进行加密认证

RSA算法RSA一、数学原理二、实现代码1 生成素数2 生成秘钥3 对数据进行加密、解密总结RSA RSA是一种非对称加密体制&#xff0c;由公钥和私钥组成&#xff0c;数学原理是实数域的模余法。在使用私钥对数据进行加密后&#xff0c;可用公钥对数据进行解密。 在RSA算法中&#xf…

他研究了5000家AI公司,说人工智能应用该这么做!

来源&#xff1a;公众号InfoQ编辑&#xff1a;陈思 Eva&#xff1b;视频剪辑&#xff1a;汪春良 概要&#xff1a;本文作者 Henry Shi是美国人工智能的博士&#xff0c;连续创业者&#xff0c;专注于 AI 领域的早期投资&#xff08;AI List Capital管理合伙人&#xff09;。无…

简明Python教程学习笔记_6_面向对象编程

面向对象编程&#xff1a;https://www.liaoxuefeng.com/wiki/897692888725344/923030496738368面向对象高级编程&#xff1a;https://www.liaoxuefeng.com/wiki/897692888725344/9230305380126401、类、对象 类 和 对象 是面向对象编程的两个主要方面。 类 是创建一个 新类型&a…

哈希值+非对称加密+网络+数字签名,你真的知道怎么给游戏充钱吗

前文 使用socket实现局域网不同主机通信 SHA256算法的实现和消息的哈希散列值计算 python实现RSA算法&#xff0c;对数据进行加密认证 文章目录数字签名与认证攻击类型算法选择实现流程总结数字签名与认证 什么是数字签名&#xff1f; 签名我们大家都知道&#xff0c;A在纸上签…

2017 年脑机接口研发热点回眸

来源&#xff1a;科技导报概要&#xff1a;脑机接口&#xff08;brain-computer interface&#xff0c;BCI&#xff09;通过解码人类思维活动过程中的脑神经活动信息&#xff0c;构建大脑与外部世界的直接信息传输通路&#xff0c;在神经假体、神经反馈训练、脑状态监测等领域有…

地牢房间迷宫走廊生成(二),Python实现洪水法、完美迷宫

文章目录前言1 随机房间和房门2 生成走廊2.1生成迷宫2.4 使用循环改进2.3 走廊缩减2.3 走廊再简化总结前言 前面通过随机房间、房门&#xff0c;对房门寻路生成走廊。由于使用A星算法&#xff0c;寻到的是最短路径&#xff0c;这样生成的走廊过直和简单。如果需要生成弯曲的走廊…

Introduce Parameter Object(引入参数对象)

某些参数总是很自然地同时出现 重构&#xff1a;以一个对象取代这些参数

深度解析,马斯克最新发射的先进火箭

来源&#xff1a;环球时报概要&#xff1a;就在几个小时前&#xff0c;美国人成功发射了目前全世界运载能力最强的超级火箭——“猎鹰重型”。就在几个小时前&#xff0c;美国人成功发射了目前全世界运载能力最强的超级火箭——“猎鹰重型”。虽然中芯级火箭在回收过程中坠毁&a…

技术专栏 | 两万字深度长文!从原理到趋势 解剖风口上的区块链技术

来源&#xff1a;芯师爷概要&#xff1a;区块链不是一项新技术&#xff0c;而是一个新的技术组合。其关键技术包括P2P动态组网、基于密码学的共享账本、共识机制、智能合约等技术。区块链不是一项新技术&#xff0c;而是一个新的技术组合。其关键技术包括P2P动态组网、基于密码…

Python 进阶

​Python 进阶&#xff1a;https://eastlakeside.gitbook.io/interpy-zh/ Python 经典教程 专题 系列&#xff1a;https://www.jb51.net/Special/520.htm Python 黑魔法指南&#xff1a;https://magic.iswbm.com/ Python 中文指南&#xff1a;https://python.iswbm.com/ Python…

2018年中国65家机器人产业园布局与规划汇总盘点

来源&#xff1a;机器人创新生态概要&#xff1a;“机器人换人”大潮下&#xff0c;中国已连续两年坐上世界机器人最大消费国的宝座&#xff0c;根据国际机器人联合会&#xff08;IFR&#xff09;发布的数据&#xff0c;2016年中国工业机器人的销量为9万台&#xff0c;同比增长…

人工智能与经济学:关于近期文献的一个综述

来源&#xff1a;财新网概要&#xff1a;相比于之前的历次技术进步&#xff0c;“人工智能革命”所引发的冲击更为巨大&#xff0c;其对经济学造成的影响也将更为广泛和深远。人工智能技术的突飞猛进&#xff0c;对经济社会的各个领域都产生了重大影响&#xff0c;这种影响当然…

Pull Up Field(字段上移)

两个子类拥有形同的字段 重构&#xff1a;将该字段移至超类

DeepMind推出分布式深度强化学习架构IMPALA,让一个Agent学会多种技能

维金 编译自 DeepMind Blog量子位 出品 | 公众号 QbitAI目前&#xff0c;深度增强学习&#xff08;DeepRL&#xff09;技术在多种任务中都大获成功&#xff0c;无论是机器人的持续控制问题&#xff0c;还是掌握围棋和雅达利的电子游戏。不过&#xff0c;这些方面的进展仅限于孤…

AAAI2018正式落幕 13个世界顶尖AI教授都讲了啥?

来源&#xff1a;智东西概要&#xff1a;2月8日消息&#xff0c;第32届AAAI大会在美国新奥尔良正式闭幕。2月8日消息&#xff0c;第32届AAAI大会在美国新奥尔良正式闭幕。本次大会不仅颁发了最佳论文奖、最佳学生论文奖、经典论文将等一系列奖项。作为顶级学术会议之一&#xf…

Linux 中 VIM 的使用

Vim 官网&#xff1a;http://www.vim.org/ VIM 实用技巧&#xff1a;https://wenku.baidu.com/view/21c5f387d4d8d15abe234ecb.html vim 的一些小技巧&#xff1a;https://www.douban.com/group/topic/1815089 vim 简单实用的技巧总结&#xff1a;http://www.tuicool.com/arti…