六、模块

六、模块

  一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀

  为何要使用模块:

  如果你退出python解释器然后重新进入,那么你之前定义的函数或者变来那个都将丢失,因此我们通常将程序写到文件中以便永久保存下来,需要时就通过python test.py方式去执行,此时test.py被称为脚本script

  随着程序的发展,功能越来越多,为了方便管理,我们通常将程序分成一个个的文件,这样做程序的结构更清晰,方便管理。这时我们不仅仅可以把这些文件当作脚本去执行,还可以把他们当作模块来导入到其他的模块中,实现了功能的重复利用

  常用模块

  collections模块

  在内置数据类型(dict、list、set、tuple)的基础上,collections模块还提供了几个额外的数据类型:Counter、deque、defaultdict、namedtuple和OrderedDict等。

  1)namedtuple:生成可以使用名字来访问元素内容的tuple

  我们知道tuple可以表示不变集合,例如,一个点的二维坐标可以表示成:

p = (1,2)

  但是,看到(1,2)很难看出这个tuple是用来表示一个坐标

  这时,namedtuple就派上了用场

#namedtuple('名称',[属性list])
from collections import namedtuple
point = namedtuple('point',['x','y'])
p = point(1,2)
p.x
p.y

  类似的,如果要用坐标和半径表示一个圆,也可以用namedtuple定义:

circle = namedtuple('circle',['x','y','r'])

  2)deque:双端队列,可以快速的从另外一侧追加和推出对象

  使用list存储数据时,按索引访问元素很快,但是插入和删除元素就很慢了,因为list是线性存储,数据量大的时候,插入和删除效率很低

  deque是为了高效实现插入和删除操作的双向列表,适合用于队列和栈

from collections import deque
q = deque(['a','b','c'])
q.append('x')
q.appendleft('y')
q

  deque除了实现list的append()和pop()外,还支持appendleft()和popleft(),这样就可以非常高效地往头部添加或删除元素

  3)OrderedDict:有序字典

  使用dict时,key是无序的,在对dict做迭代时,我们无法确定key的顺序

  如果要保持key的顺序,可以用OrderedDict:

from collections import OrderedDict
d = dict([('a',1),('b',2),('c',3)])
d #dict的key是无序的
od = OrderedDict([('a',1),('d',2),('c',3)])
od #OrderedDict的key是有序的
OrderedDict([('a', 1), ('d', 2), ('c', 3)]) #注意,OrderedDict的key会按照插入的顺序排列,不是key本身排序

  4)defaultdict:带有默认值的字典

  有如下值集合[11,22,33,44,55,66,77,88,99,90...],将所有大于66的值保存至字典的第一个key中,将小于66的值保存至第二个key的值中

  即: {'k1': 大于66 'k2': 小于66}

  

  1.使用模块

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

import sys
    def test():
        args = sys.argv
        if len(args)==1:
            print('Hello,world!')
        elif len(args)==2: print('Heool,%s!'%args[1]) else: print('Too many arguments') if __name__=='__main__': test()

  导入sys模块后,我们就有了变量sys指向该模块,利用sys这个变量,就可以访问sys模块所有功能
  sys模块有一个argv变量,用list存储了命令行的所有参数。argv至少有一个元素,因为第一个参数永远是该.py文件的名称,例如:
  运行python3 hello.py获得的sys.argv就是['hello.py']
  运行python3 hello.py Michael获得的sys》argv就是['hello.py','Michael']
  最后,注意到这两行代码

if __name__ == '__main__':
test()

  当我们在命令行运行hello模块文件时,python解释器把一个特殊变量__name__置为__main__,而如果在其他地方导入该hello模块时,if判断将失败
  因此,这种if测试可以让一个模块通过命令行运行时执行一些额外的代码,最常见的就是运行测试

  作用域
  在一个模块中,我们可能会定义很多的函数和变量,但有的函数和变量我们希望给别人使用,有的函数和变量我们希望仅仅在模块内部使用,在python中,是通过_前缀来实现的
  正常的函数和变量名是公开的(public),可以被直接引用,比如:abc,x123,pi等
  类似__xx__这样的变量是特殊变量,可以被直接引用,但是有特殊用途,比如上面的__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

  2.安装第三方模块
  python模块,是一个python文件,以.py结尾,一个.py文件就称之为一个模块(Module),包含了python对象定义和python语句
  模块让你能够有逻辑地组织你的python代码段
  把相关的代码分配到一个模块里能让你的代码更好用,更易懂
  模块能定义函数,类和变量,模块里也能包含可执行的代码

  举个例子,一个abc.py的文件就是一个名字叫abc的模块,一个xyz.py的文件就是一个名字叫xyz的模块,假设我们的abc和xyz这两个模块名字与其他模块冲突了,于是我们可以通过包来组织模块。若放在了mycompany,此时abc.py模块的名字就变成了mycompany.abc,类似的,xyz.py的模块名变成了mycompany.xyz

  import 语句

  模块的引入
  模块定义好后,我们可以使用import语句来引入模块,语法如下:
  import module1[,module2[,...moduleN]]
  比如要引用模块math,就可以在文件最开始的地方用import math来引入,在调用math模块中的函数时,必须这样引用:模块名.函数名
  当解释器遇到import语句,如果模块在当前的搜索路径就会被导入
  搜索路径是一个解释器会先进行搜索的所有目录的列表,如想要导入模块support.py,需要把命令放在脚本的顶端

  导入模块:
  import support
  现在可以调用模块里包含的函数了
  support.print_func('Runoob')
  一个模块只会被导入一次,不管你之行了多少次import,这样可以防止导入模块被一遍又一遍地执行

  from...import语句
  python的from语句让你从模块中导入一个指定的部分到当前命名空间中,语法如下:
  from modname import name1[,name2[,...nameN]]
  例如要导入模块fib的fibonacci函数,使用如下语句:
  from fib import fibnacci
  这个声明不会把整个fib模块导入到当前的命名空间中,他只会将fib里的fibonacci单个引入到执行这个声明的模块的全局符号表

  from...import* 语句
  把一个模块的所有内容全都导入到当前的命名空间也是可行的,只是需要使用如下声明:
  from modname import *
  这提供了一个简单的方法来导入一个模块中的所有项目,然而这种声明不该被过多的使用
  例如我们想一次性引入math模块中所有的东西,语法如下:from math import *

  搜索路径
  当你导入一个模块,python解析器对模块位置的搜索顺序是:
  1.当前目录
  2.如果不在当前目录,python则搜索在shell变量PYTHONPATH下的每个目录
  3.如果都找不到,python会查看默认路径,UNIX下,默认路径一般为/usr/local/lib/python/
  模块搜索路径存储在system模块的sys.path变量中,变量里包含当前目录,PYTHONPATH和由安装过程决定的默认目录

  PYTHONPATH变量
  作为环境变量,PYTHONPATH由装在一个列表里的许多目录组成,PYTHONPATH的语法和shell变量PATH一样

  在python中,安装第三方模块,是通过包管理工具pip完成的
  如果你正在使用Mac或linux,安装pip本身这个步骤就可以跳过;#如果你正在使用windows,请参考安装python一节的内容,确保安装勾选了pip和Add python.exe to path
在命令提示符窗口下尝试运行pip,如果windowd提示未找到命令,可以重新运行安装程序调价pip
  pip install Pillow

猜你喜欢

转载自www.cnblogs.com/blogbo/p/11753543.html