python-模块系列

模块,用一砣代码实现了某个功能的代码集合。 

类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合。而对于一个复杂的功能来,可能需要多个函数才能完成(函数又可以在不同的.py文件中),n个 .py 文件组成的代码集合就称为模块。

如:os 是系统相关的模块;file是文件操作相关的模块

模块分为三种:

  • 自定义模块
  • 第三方模块
  • 内置模块

自定义模块

自定义模块很好理解了,就是自己写的模块,它可以是一个.py的文件,也可以是一个文件夹(如果是文件夹必须有__int__的目录才是模块,否则就是一个普通目录)

1.定义模块

day12就是一个模块,因为存在__init__.py,day7就不是一个模块,因为没有__init__.py文件

一定有人会在心里问__init__.py里面是啥,为啥就这么吊,有它就是模块,没它就不是模块

最终结果却令人大失所望,__init__.py里面啥都木有,说白了就是一个空文件,但是你没有它就不行,就不是模块而是文件夹,如果你建了一个文件夹,又想变成模块,你自己在里面创建一个__init__.py就行了。

2.导入模块

Python之所以应用越来越广泛,在一定程度上也依赖于其为程序员提供了大量的模块以供使用,如果想要使用模块,则需要导入。导入模块有一下几种方法:

1 import module
2 from module.xx.xx import xx
3 from module.xx.xx import xx as rename 
4 from module.xx.xx import *

导入模块其实就是告诉Python解释器去解释那个py文件

  • 导入一个py文件,解释器解释该py文件
  • 导入一个包,解释器解释该包下的 __init__.py 文件 【py2.7】

那么问题来了,导入模块时是根据那个路径作为基准来进行的呢?即:sys.path

import sys
print sys.path

结果:
['', '/usr/lib64/python26.zip', '/usr/lib64/python2.6', '/usr/lib64/python2.6/plat-linux2', '/usr/lib64/python2.6/lib-tk', '/usr/lib64/python2.6/lib-old', '/usr/lib64/python2.6/lib-dynload', '/usr/lib64/python2.6/site-packages', '/usr/lib/python2.6/site-packages', '/usr/lib/python2.6/site-packages/setuptools-0.6c11-py2.6.egg-info']

如果sys.path路径列表没有你想要的路径,可以通过 sys.path.append('路径') 添加。

1 import sys
2 import os
3 project_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
4 sys.path.append(project_path)

内置模块

内置模块说白了就是python系统自带的一些常用模块,将一些常用的模块封装到了里面,在你使用的时候不用去安装,直接去引用就可以了。

1.sys模块

用于提供对Python解释器相关的操作:

1 sys.argv           命令行参数List,第一个元素是程序本身路径
2 sys.exit(n)        退出程序,正常退出时exit(0)
3 sys.version        获取Python解释程序的版本信息
4 sys.maxint         最大的Int值
5 sys.path           返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
6 sys.platform       返回操作系统平台名称
7 sys.stdin          输入相关
8 sys.stdout         输出相关
9 sys.stderror       错误相关

实例展示:

 1 sys.argv #命令行参数List,第一个元素是程序本身路径
 2 print sys.argv
 4 python /root/test.py 123
 5 返回结果:['/root/test.py', '123']
 6 
 7 sys.exit(n)        #退出程序,正常退出时exit(0)
 8 
 9 sys.version         #获取Python解释程序的版本信息
10 返回结果:
11 2.6.6 (r266:84292, Nov 22 2013, 12:16:22) 
12 [GCC 4.4.7 20120313 (Red Hat 4.4.7-4)]
13 
15 sys.path    #返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
16 返回结果:
17 ['', '/usr/lib64/python26.zip', '/usr/lib64/python2.6', '/usr/lib64/python2.6/plat-linux2', '/usr/lib64/python2.6/lib-tk', '/usr/lib64/python2.6/lib-old', '/usr/lib64/python2.6/lib-dynload', '/usr/lib64/python2.6/site-packages', '/usr/lib/python2.6/site-packages', '/usr/lib/python2.6/site-packages/setuptools-0.6c11-py2.6.egg-info']
18 
19 sys.platform    #返回操作系统名称
20 返回结果:
21 'linux2'
22 
23 sys.builtin_module_names #列表包含 Python 解释器中所有内建模块的名称
24 返回结果:
25 ('__builtin__', '__main__', '_ast', '_codecs', '_sre', '_symtable', '_warnings', 'errno', 'exceptions', 'gc', 'imp', 'marshal', 'posix', 'pwd', 'signal', 'sys', 'thread', 'zipimport')
26 
27 sys.modules #字典包含所有加载的模块. import 语句在从磁盘导入内容之前会先检查这个字典.
28 返回结果:
29 {'abrt_exception_handler': <module 'abrt_exception_handler' from '/usr/lib64/python2.6/site-packages/abrt_exception_handler.pyc'>, 'os': <module 'os' from '/usr/lib64/python2.6/os.pyc'>}

标准输出和标准错误 (通常缩写为 stdout 和 stderr) 是内建在每一个 UNIX 系统中的管道。
当你 print 某些东西时,结果前往 stdout 管道;
当你的程序崩溃并打印出调试信息 (例如 Python 中的 traceback (错误跟踪)) 的时候,信息前往 stderr 管道

 1 sys.stdout         #输出相关
 2 for i in range(3):
 3     print'Dive in'
 4     
 5 Dive in
 6 Dive in
 7 Dive in
 8 import sys
 9 for i in range(3):
10     sys.stdout.write('Dive in')
11 
12 Dive inDive inDive in
13 for i in range(3):
14     sys.stderr.write('Dive in')
15 
16 Dive inDive inDive in
17     sys.stderror #错误相关

stdout 是一个类文件对象;调用它的 write 函数可以打印出你给定的任何字符串。

实际上,这就是 print 函数真正做的事情;它在你打印的字符串后面加上一个硬回车,然后调用 sys.stdout.write 函数。

在最简单的例子中,stdout 和 stderr 把它们的输出发送到相同的地方

和 stdout 一样,stderr 并不为你添加硬回车;如果需要,要自己加上。

stdout 和 stderr 都是类文件对象,但是它们都是只写的。

它们都没有 read 方法,只有 write 方法。然而,它们仍然是类文件对象,因此你可以将其它任何 (类) 文件对象赋值给它们来重定向其输出。

重定向展示

 1 #!/usr/bin/env python
 2 #-*-coding:utf-8-*-
 3 
 4 import sys
 5 
 6 print 'Dive in'        # 标准输出,输出到终端上
 7 saveout = sys.stdout        # 终在重定向前保存stdout,这样的话之后你还可以将其设回正常
 8 fsock = open('/root/out.log', 'w')      # 打开一个新文件用于写入。如果文件不存在,将会被创建。如果文件存在,将被覆盖。
 9 sys.stdout = fsock                 # 所有后续的输出都会被重定向到刚才打开的新文件上。
10 
11 print  'This message will be logged instead of displayed'    # 这样只会将输出结果“打印”到日志文件中;屏幕上不会看到输出
12 
13 sys.stdout = saveout   # 在我们将 stdout 搞乱之前,让我们把它设回原来的方式。    
14 print 'dsadasdadadasdadasda' # 标准输出,输出到终端上
15 fsock.close()     # 关闭日志文件。

结果展示:

这就是 print 函数真正做的事情;它在你打印的字符串后面加上一个硬回车,然后调用 sys.stdout.write 函数

sys.stdin实例:

1 import sys
2 
3 while True:
4     print '请输入两个数字,中间用空格隔开'
5     line = sys.stdin.readline()
6     if not line:
7         break
8     a = line.split()
9     print int(a[0]) + int(a[1])

关于raw_put()和readline()的区别:解析文章:http://www.cnblogs.com/dolphin0520/archive/2013/03/27/2985492.html

sys.stdin.readline( )会将标准输入全部获取,包括末尾的'\n',但是raw_input( )获取输入时返回的结果是不包含末尾的换行符'\n'的。

小实例:模拟进度条:

#!/usr/bin/env python
# _*_ coding:utf-8 _*_
import sys
for i in range(101):
   #显示进度条百分比  #号从1开始 空格从99递减
   hashes = '#' * int(i / 100.0 * 100)
   sys.stdout.write("\r%s %s%%" % (hashes, i))  #必须两个%%才是,因为一个%是取模,python解释器会默认过滤
   sys.stdout.flush() #强制刷新屏幕缓冲区使其一行输出
   time.sleep(0.5)

2.os模块

 用于提供系统级别的方案

 1 os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径
 2 os.chdir("dirname")  改变当前脚本工作目录;相当于shell下cd
 3 os.curdir  返回当前目录: ('.')
 4 os.pardir  获取当前目录的父目录字符串名:('..')
 5 os.makedirs('dirname1/dirname2')    可生成多层递归目录
 6 os.removedirs('dirname1')    若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
 7 os.mkdir('dirname')    生成单级目录;相当于shell中mkdir dirname
 8 os.rmdir('dirname')    删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
 9 os.listdir('dirname')    列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
10 os.remove()  删除一个文件
11 os.rename("oldname","newname")  重命名文件/目录
12 os.stat('path/filename')  获取文件/目录信息
13 os.sep    输出操作系统特定的路径分隔符,win下为"\\",http://edu.51cto.com/index.php?do=lesson&id=103882Linux下为"/"
14 os.linesep    输出当前平台使用的行终止符,win下为"\t\n",Linux下为"\n"
15 os.pathsep    输出用于分割文件路径的字符串
16 os.name    输出字符串指示当前使用平台。win->'nt'; Linux->'posix'
17 os.system("bash command")  运行shell命令,直接显示
18 os.environ  获取系统环境变量
19 os.path.abspath(path)  返回path规范化的绝对路径
20 os.path.split(path)  将path分割成目录和文件名二元组返回
21 os.path.dirname(path)  返回path的目录。其实就是os.path.split(path)的第一个元素
22 os.path.basename(path)  返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素
23 os.path.exists(path)  如果path存在,返回True;如果path不存在,返回False
24 os.path.isabs(path)  如果path是绝对路径,返回True
25 os.path.isfile(path)  如果path是一个存在的文件,返回True。否则返回False
26 os.path.isdir(path)  如果path是一个存在的目录,则返回True。否则返回False
27 os.path.join(path1[, path2[, ...]])  将多个路径组合后返回,第一个绝对路径之前的参数将被忽略
28 os.path.getatime(path)  返回path所指向的文件或者目录的最后存取时间
29 os.path.getmtime(path)  返回path所指向的文件或者目录的最后修改时间

3.hashlib

用于加密相关的操作,代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法

最常用的md5方法:

1 import hashlib
2 
3 hash = hashlib.md5() #以md5方式加密
4 hash.update('abcd') #更新哈希对象,以字符串
5 print hash.hexdigest()#返回十六进制数字字符串e2fc714c4727ee9395f324cd2e7f331f
6 print hash.digest() #返回摘要,作为二进制数据字符串值

查看支持的加密算法:

1 print hashlib.algorithms     #列出所有加密算法
2 #('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512')

各种加密实例展示:

 1 import hashlib
 2 
 3 # ######## md5 ########
 4 hash = hashlib.md5() #以md5的方式加密
 5 hash.update('admin')
 6 print hash.hexdigest()
 7 print hash.digest()
 8 
 9 ######## sha1 ########
10 
11 hash = hashlib.sha1()#以sha1的方式加密
12 hash.update('admin')
13 print hash.hexdigest()
14 
15 # ######## sha256 ########
16 
17 hash = hashlib.sha256() #以sha256的方式加密
18 hash.update('admin')
19 print hash.hexdigest()
20 
21 
22 # ######## sha384 ########
23 
24 hash = hashlib.sha384() #以sha384的方式加密
25 hash.update('admin')
26 print hash.hexdigest()
27 
28 # ######## sha512 ########
29 
30 hash = hashlib.sha512() #以sha512的方式加密
31 hash.update('admin')
32 print hash.hexdigest()

这么多方式,能不能把加密方式当参数传入啊,python当然可以啦,人生苦短我用python啊!

 1 new(name, string='') #用new 方法,name是指定的加密方式,string是加密的字符串,这地方可以和update一起用,组成加盐方式加密
 2      """
 3      Return a new hashing object using the named algorithm;
 4      optionally initialized with a string.
 5      """
 6 import hashlib
 7 #这两个方式其实是一样,但是用new方法更灵活,可以传如加密方式
 8 h = hashlib.new('md5')
 9 print h     
10 h.update('beginman')
11 print h.hexdigest() #666fc5baa93a7fb207c5bfff03b67732
12 
13 s = hashlib.md5()
14 s.update('beginman')
15 print s.hexdigest() #666fc5baa93a7fb207c5bfff03b67732

以上加密算法虽然依然非常厉害,但时候存在缺陷,即:通过撞库可以反解。所以,有必要对加密算法中添加自定义key再来做加密。

1 hash = hashlib.md5('wolegequ')#这个地方的是你自己在程序里面加的,不要轻易告诉别人,这样相当于自己又加了遇到防线。
2 hash.update('zhemediao')
3 print hash.hexdigest()
#d38300d8efb8f70d5828487ff7ca917

 还有厉害的加密方法:python 还有一个 hmac 模块,它内部对我们创建 key 和 内容 再进行处理然后再加密。

import hmac
h = hmac.new('wolegequ')
h.update('zhemediao')
print h.hexdigest()
#31f4ff4c716b9bc8d12009fc336c5fd2

增量更新文件太大的时候,可以分多次读入:就是将加密的字符串割成小字符串。

 1 import hashlib
 2 hash = hashlib.md5('wolegequ')
 3 hash.update('zhemediao')#可以切割成多个使用update方法
 4 hash.update('bixude')#
 5 print hash.hexdigest()
 6 #6cf2ea119f173704dea8860281df3313
 7 
 8 #这个方法和一次更新的结果一样
 9 hash1 = hashlib.md5('wolegequ')
10 hash1.update('zhemediaobixude')#一整次更新
11 print hash1.hexdigest()
12 #6cf2ea119f173704dea8860281df3313

属性hashlib.algorithms包含支持的算法。

属性hash.digest_size :结果hash的大小

属性hash. block_size : hash内部块的大小

 1 #!/usr/bin/env python
 2 #-*- coding:utf-8 -*-
 3 __author__ = 'wyf'
 4 
 5 import hashlib
 6 
 7 def md5(passwd):
 8     hash = hashlib.md5('admin')
 9     hash.update(passwd)
10     return hash.hexdigest()
11 
12 def registered (user,passwd):#注册用户函数
13     with open('db.conf','a') as f:
14         temp = user +'|'+ md5(passwd)
15         f.write(temp+'\n')
16 
17 def login(user,passwd):
18     with open('db.conf','r') as f1:
19         for i in f1:
20             u,p = i.strip().split('|')
21             if u == user and p == md5(passwd):
22                 return  True
23 def main():
24     print u'1、登录;2、注册;3.退出'
25     chooseNum = raw_input('请输入选择的操作》》》:')
26     if chooseNum == '1':
27         user = raw_input('请输入用户名》》》:')
28         passwd = raw_input('请输入密码》》》:')
29         if login(user,passwd):
30             print '登录成功'
31         else:
32             print '登录失败'
33 
34     elif chooseNum =='2':
35         user = raw_input('请输入用户名》》》:')
36         passwd = raw_input('请输入密码》》》:')
37         registered(user,passwd)
38 
39 
40 if __name__ == '__main__':
41     main()
登录小练习

4.json和pickle

用于序列化的两个模块

  • pickle,用户python特有的类型和python的数据类型间进行转换。
  • json,用于字符串和python的数据类型间进行转换。

pickle模块:

pickle模块使用的数据格式是python专用的,并且不同版本不向后兼容,同时也不能被其他语言识别。要和其他语言交互,可以使用内置的json包,使用pickle模块你可以把python对象直接保存到文件,而不需要把他们转化为字符串,也不用底层的文件访问操作把它们写入到一个二进制文件里。 pickle模块会创建一个python语言专用的二进制格式,你基本上不用考虑任何文件细节,它会帮你干净利落地完成读写独享操作,唯一需要的只是一个合法的文件句柄。

pickle模块中的两个主要函数是dump()和load()。dump()函数接受一个文件句柄和一个数据对象作为参数,把数据对象以特定的格式保存到给定的文件中。当我们使用load()函数从文件中取出已保存的对象时,pickle知道如何恢复这些对象到它们本来的格式。
        dumps()函数执行和dump() 函数相同的序列化。取代接受流对象并将序列化后的数据保存到磁盘文件,这个函数简单的返回序列化的数据。
        loads()函数执行和load() 函数一样的反序列化。取代接受一个流对象并去文件读取序列化后的数据,它接受包含序列化后的数据的str对象, 直接返回的对象。

dumps和dump区别展示:

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

s = '{"desc":"ininia","status":200,"aaa":[11,22,33,44,55,66]}'

f = open('abc.txt','r+') 
a = pickle.dump(s,f) #dump除了传存储对象还有 打开的文件句柄
f.close()

f1 = open('abc1.txt','r+')
a1 = pickle.dumps(s) # dumps 直接传存储对象
f.write(a1)
f.close()

 loads和load是dumps和dump的反操作因此都一样。

json模块:

似乎pickle已经和吊了,能满足几乎所有的序列化和反序列话,但是不要忘记前面提到的pickle只是python特有的操作,只能python才能操作,如果这样的话是不是太局限了?这时候json就有存在的意义了,它可以跨语言进行数据交换,基本上大多数语言都支持json,如果是两个跨语言的数据交换,json是最好的选择,你只要说哥们json吧。但是有一点必须注意,json是很多语言都支持,这也导致了一些局限性,有些python支持的数据类型,json不支持,因此json序列化一般为字典和列表

json的用法和pickle一样,提供了四个功能:dumps、dump、loads、load。

实例:

 1 s = '{"desc":"ininia","status":200,"aaa":[11,22,33,44,55,66]}'
 2 s1 = {"desc":"ininia","status":200,"aaa":[11,22,33,44,55,66]}
 3 import json
 4 result = json.loads(s)#将字符串转换成对象
 5 print result,type(result)
 6 #{u'status': 200, u'aaa': [11, 22, 33, 44, 55, 66], u'desc': u'ininia'} <type 'dict'>
 7 
 8 result1 = json.dumps(s1)#将对象转换成字符串
 9 print result1,type(result1)
10 #{"status": 200, "aaa": [11, 22, 33, 44, 55, 66], "desc": "ininia"} <type 'str'>

 

posted @ 2015-12-08 11:00  楚时邀月  阅读(277)  评论(0编辑  收藏  举报