random模块用于获取随机数,一下random模块中经常使用的函数:python
# 返回 (0,1) ,float类型 random.random() # 返回 [1,3],int 类型 random.randint(1, 3) # 返回 [1,3),int 类型 random.randrange(1, 3) # 随机获取列表中的一个元素 random.choice([3,4,5,2,1, 'kitty']) # 随机获取列表中的2个元素,以列表的形式返回 random.sample([3,4,5,2,1, 'kitty'], 2) # 返回[1,3],float类型 random.uniform(1,3) # 随机打乱 类表lst 中的元素顺序 lst = [111,222,333,444] random.shuffle(lst)
示例(随机获取验证码),5位验证码,包含整数,大小写字母~算法
def valdate_code(): res = '' for i in range(5): num = random.randint(0, 9) alpha_lower = chr(random.randint(97, 122)) # 小写字母 alpha_upper = chr(random.randint(65, 90)) # 大写字母 s = random.choice([str(num), alpha_lower, alpha_upper]) res += s return res 调用结果: 8Rj0x 306GX ...
hashlib模块提供了常见的摘要算法,如MD5,SHA1等。
摘要算法是指 经过一个函数,将任意长度的数据转换为一个固定长度的字符串,一般用16进制的字符串表示~shell
import hashlib md5_obj = hashlib.md5() md5_obj.update(b"hello world") print(md5_obj.hexdigest()) # 5eb63bbbe01eeed093cb22bb8f5acdc3 # 如今对hello world改变一个字母 md5_obj.update(b"hello World") print(md5_obj.hexdigest()) # 4245dd40eaf3111caa3c8f9e3ceeed3c
数据由 'hello world' 改为 'hello World',获取的摘要信息彻底不相同。因此摘要算法通常用于提取数据的特征码。数据库
摘要函数是一个单向函数,经过数据计算出其特征码很容易,可是要根据特征码反推出数据却很困难。经过从数据中提取出的特征码能够判断数据是否被篡改过~安全
若如今要获取一个大文件的特征码,能够每读取一行,对这一行的数据进行一次update(),到最后再进行特征码的计算,示例以下:bash
import hashlib md5_obj = hashlib.md5() with open(file='/Users/luyi/tmp/passwd', mode='r', encoding='utf-8') as f: for line in f: md5_obj.update(line.encode('utf-8')) print(md5_obj.hexdigest())
Tip:在python3中,传递给update的参数必须是 bytes 类型。python3中字符串默认使用 unicode 形式保存在内存中,须要将 unicode 形式的字符串 encode 为 bytes 类型再进行操做~dom
上述示例中使用的摘要算法都是md5,md5是常见的摘要算法,生成速度快,生成的结果是一个固定的128 bit字节,一般用一个32位的16进制字符串表示。除了md5还有一种摘要算法sha1,调用sha1的方式与调用md5相似,sha1的结果是160 bit字节,一般用一个40位的16进制字符串表示。ide
import hashlib sha1_obj = hashlib.sha1() sha1_obj.update(b'hello world') sha1_obj.update(b'hello kitty') print(sha1_obj.hexdigest()) # 563258876190465d493543b96306a92164ac7e62
除了md5,sha1算法,还有 sha256 和 sha512,这两个摘要算法获取的摘要长度更长,更安全,可是计算的速度会更慢~函数
获取数据的特征码,数据的长度是任意的,可是获取的特征码(摘要信息)的长度是固定的,那就有可能出现这种状况,两个不同的数据,提取的特征码是一致的,这种状况称为碰撞,只是发生的几率不大~测试
摘要算法还一般用于密码的保存,密码先进行单向加密后,而后再保存到数据库中。当须要验证密码时,将用户输入的密码也进行单向加密,而后和数据库中存储的进行比对~
可是这样就又有一个问题,若用户设置的密码过于简单,例如不少人会使用 '123456','admin','password'这样的密码,若公司存放用户信息的表丢失,嘿客能够事先计算出这些简单密码的md5值,而后与表中加密后的密码进行比对,这样部分用户的密码就会被嘿客获取。
e10adc3949ba59abbe56e057f20f883e 123456 21232f297a57a5a743894a0e4a801fc3 admin 5f4dcc3b5aa765d61d8327deb882cf99 password
解决的方法就是,对原始的密码“加盐操做”。即对原始的密码再加上其特有的字符串,例如将用户的密码再加上其用户名,而后再进行单项加密操做~,这样即便用户使用的密码相同,加上用户名后获取的摘要信息也不会相同~
import hashlib md5_obj = hashlib.md5(b'kitty') # 在这里进行加盐 md5_obj.update(b"123456") print(md5_obj.hexdigest())
os 模块是与操做系统交互的一个接口
经常使用方法以下:
os.getcwd() # 获取当前工做目录,即当前python脚本工做的目录路径 os.chdir("dirname") # 改变当前脚本工做目录;至关于shell下cd os.curdir # 返回当前目录: ('.') os.pardir # 获取当前目录的父目录字符串名:('..’) os.makedirs('dirname1/dirname2') # 可生成多层递归目录 os.removedirs('dirname1') # 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推 os.mkdir('dirname') # 生成单级目录;至关于shell中mkdir dirname os.rmdir('dirname') # 删除单级空目录,若目录不为空则没法删除,报错;至关于shell中rmdir dirname os.listdir('dirname') #列出指定目录下的全部文件和子目录,包括隐藏文件,并以列表方式打印 os.remove() # 删除一个文件 os.rename("oldname","newname") # 重命名文件/目录,注意若文件未打开状态,则没法rename os.stat('path/filename') # 获取文件/目录信息 os.sep # 输出操做系统特定的路径分隔符,win下为"\\",Linux下为"/" os.linesep # 输出当前平台使用的行终止符,win下为"\t\n",Linux下为"\n" os.pathsep # 输出用于分割文件路径的字符串 win下为;,Linux下为: 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.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.getsize(path) # 返回path的大小
常常会使用的就以下几个:
os.remove() os.path.abspath(path) os.path.abspath(__file__) # 获取当前执行脚本的路径 os.path.dirname(path) os.path.basename(path) os.path.exists(path) os.path.isfile(path) os.path.isdir(path) os.path.join(path1[, path2[, ...]]) os.path.join('/','etc', 'passwd') # /etc/passwd os.path.getsize(path) os.path.getsize('/etc/passwd') # 6804,单位字节
os.access() 用来检测指定路径的访问权限~
语法:os.access(path, mode); - path:用来检测的路径,能够是目录,也能够是文件~ - mode: - os.F_OK: 测试path是否存在。 - os.R_OK: 测试path是否可读。 - os.W_OK: 测试path是否可写。 - os.X_OK: 测试path是否可执行。
示例:
import os # 判断目录是否存在 res = os.access("/tmp", os.F_OK) print "F_OK - %s"% res # 判断文件是否存在 res = os.access("/tmp/abc", os.F_OK) print "F_OK - %s"% res # 判断目录是否可读 res = os.access("/tmp", os.R_OK) print "R_OK - %s"% res # 判断文件是否可读 res = os.access("/tmp/abc", os.R_OK) print "R_OK - %s"% res # 判断文件是否可写 res = os.access("/tmp/abc", os.W_OK) print "W_OK - %s"% res # 判断文件是否可执行 res = os.access("/tmp/abc", os.X_OK) print "X_OK - %s"% res # 执行结果: F_OK - True F_OK - True R_OK - True R_OK - True W_OK - True X_OK - False
os 模块是和操做系统交互的模块,这里的sys是和python解释器交互的模块
列出经常使用方法便可
sys经常使用的方法以下:
sys.argv # 命令行参数,以List形式返回,第一个元素是程序自己路径 sys.exit(n) # 退出程序,正常退出是exit(0),参数为返回码 sys.version # 获取Python解释程序的版本信息 sys.maxint # 最大的Int值 sys.path # 返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值 sys.platform # 返回操做系统平台名称 sys.getdefaultencoding() # 获取系统当前默认编码,python2默认为ascii,python3默认为utf-8。 sys.setdefaultencoding() # python2中设置系统默认编码,执行dir(sys)时不会看到这个方法,在解释器中执行不经过,须要先执行reload(sys),再进行设置。python3中没有此方法,也不能reload(sys)~ sys.getfilesystemencoding() # 获取文件系统使用编码方式,Windows下返回'mbcs',mac下返回'utf-8'. sys.stdin,sys.stdout,sys.stderr # stdin , stdout , 以及 stderr 变量包含与标准 I/O 流对应的流对象. 若是须要更好地控制输出,而 print 不能知足要求, 可使用stdin , stdout , stderr 替换。这时候能够重定向输出或者输入到其它设备( device ),或者以非标准的方式处理它们~
经过命令行运行Python程序时,命令行的执行文件 及参数会以列表的形式存放在 sys.argv 变量中~
sys_test.py文件内容以下: import sys print(sys.argv) 命令行执行: ➜ ~ python ~/tmp/sys_test.py 1 2 3 4 5 6 ['/Users/luyi/tmp/sys_test.py', '1', '2', '3', '4', '5', '6']
程序执行完成后,python解释器自动退出,若因为某些缘由须要在中途退出,可使用 sys.exit(n) ,参数n 可指定退出时的状态码,通常n=0表示正常退出,其余数值(1-127)为非正常退出~
示例:
# 执行以下内容的py文件 import sys sys.exit(2) ➜ tmp python sys_test.py ➜ tmp echo $? 2 # 状态返回码为 2
程序的中途退出也可使用 SystemExit 进行捕获,在 except 中完成退出以前必要的事项
print('start...') try: sys.exit(1) except SystemExit: print('end...') sys.exit(0) print('contimue') # 输出结果: start... end...
sys.path 是一个列表,里面存放的是模块的搜索路径。若须要使用的模块不在这些路径中,能够直接将路径添加到这个变量中,程序中的 import 就能正确导入该模块~
>>> import sys >>> sys.path ['', '/Library/Frameworks/Python.framework/Versions/3.6/lib/python36.zip', '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6', '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/lib-dynload', '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages']
当 python程序中涉及到 unicode类型 和 编码的字符串 相互转换时 (python2 中为 str 类型 与 unicode类型相互转换,python3中为 str类型 和 bytes类型 之间的相互转换,这一块的详细内容可参见 http://www.javashuo.com/article/p-mpawubgy-w.html ) 就会使用getdefaultencoding输出的编码进行转换~
python2中默认编码为 ascii,python3中默认编码为 utf-8 ~
# python2 import sys print sys.getdefaultencoding() 输出结果: ascii # python3 import sys print(sys.getdefaultencoding()) 输出结果: utf-8
python3中,当str类型(python3中字符串一概使用unicode存放)和 bytes类型 合并时,会直接报错:
x = '你好,' # str类型 y = '贝贝'.encode('utf-8') # bytes类型 print(x + y) 报错信息: TypeError: must be str, not bytes
可是在python2中,这个过程能够进行,Python解释器会自动把 str 转换成 unicode 再进行运算,运算结果也都是 unicode类型,在Python解释器自动将 str 转成 unicode时,因为没有具体指定使用哪一种编码进行转码,因此python解释器就会默认使用 getdefaultencoding中的编码,python2中默认编码是ascii,因而就出现以下错误:
x = u'你好,' y = '贝贝' print x + y 错误信息: UnicodeDecodeError: 'ascii' codec can't decode byte 0xe8 in position 0: ordinal not in range(128)
设置一下默认编码,就能够正常输出:
# -*- coding: utf-8 -*- import sys reload(sys) sys.setdefaultencoding('utf-8') x = u'你好,' y = '贝贝' print x + y 输出结果: 你好,贝贝
Tip:这个常常在 python2 中使用,python3中没有这样的操做,sys不能 reload,也没有 setdefaultencoding 方法~,python3中默认编码为utf-8,也不须要修改~
.................^_^