热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

python常用模块(random,hashlib,os,sys)

randomrandom模块用于获取随机数,一下random模块中常用的函数:#返回(0,1),float类型random.random()#返回[1,3],int类型random

random

random模块用于获取随机数,一下random模块中常用的函数:

# 返回 (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

hashlib模块提供了常见的摘要算法,如MD5,SHA1等。
摘要算法是指 通过一个函数,将任意长度的数据转换为一个固定长度的字符串,通常用16进制的字符串表示~

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(),到最后再进行特征码的计算,示例如下:

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 类型再进行操作~

 
上述示例中使用的摘要算法都是md5,md5是常见的摘要算法,生成速度快,生成的结果是一个固定的128 bit字节,通常用一个32位的16进制字符串表示。除了md5还有一种摘要算法sha1,调用sha1的方式与调用md5类似,sha1的结果是160 bit字节,通常用一个40位的16进制字符串表示。

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 模块是与操作系统交互的一个接口
常用方法如下:

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,单位字节

sys

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 ),或者以非标准的方式处理它们~

sys.argv

通过命令行运行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']

sys.exit(n)

程序执行完成后,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

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']

sys.getdefaultencoding(),sys.setdefaultencoding()

当 python程序中涉及到 unicode类型 和 编码的字符串 相互转换时 (python2 中为 str 类型 与 unicode类型相互转换,python3中为 str类型 和 bytes类型 之间的相互转换,这一块的详细内容可参见 http://blog.51cto.com/ljbaby/2164480 ) 就会使用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,也不需要修改~

.................^_^


推荐阅读
  • Hibernate延迟加载深入分析-集合属性的延迟加载策略
    本文深入分析了Hibernate延迟加载的机制,特别是集合属性的延迟加载策略。通过延迟加载,可以降低系统的内存开销,提高Hibernate的运行性能。对于集合属性,推荐使用延迟加载策略,即在系统需要使用集合属性时才从数据库装载关联的数据,避免一次加载所有集合属性导致性能下降。 ... [详细]
  • 使用freemaker生成Java代码的步骤及示例代码
    本文介绍了使用freemaker这个jar包生成Java代码的步骤,通过提前编辑好的模板,可以避免写重复代码。首先需要在springboot的pom.xml文件中加入freemaker的依赖包。然后编写模板,定义要生成的Java类的属性和方法。最后编写生成代码的类,通过加载模板文件和数据模型,生成Java代码文件。本文提供了示例代码,并展示了文件目录结构。 ... [详细]
  • 查找给定字符串的所有不同回文子字符串原文:https://www ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • 本文介绍了如何清除Eclipse中SVN用户的设置。首先需要查看使用的SVN接口,然后根据接口类型找到相应的目录并删除相关文件。最后使用SVN更新或提交来应用更改。 ... [详细]
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
  • Java程序设计第4周学习总结及注释应用的开发笔记
    本文由编程笔记#小编为大家整理,主要介绍了201521123087《Java程序设计》第4周学习总结相关的知识,包括注释的应用和使用类的注释与方法的注释进行注释的方法,并在Eclipse中查看。摘要内容大约为150字,提供了一定的参考价值。 ... [详细]
  • Whatsthedifferencebetweento_aandto_ary?to_a和to_ary有什么区别? ... [详细]
  • HashMap的相关问题及其底层数据结构和操作流程
    本文介绍了关于HashMap的相关问题,包括其底层数据结构、JDK1.7和JDK1.8的差异、红黑树的使用、扩容和树化的条件、退化为链表的情况、索引的计算方法、hashcode和hash()方法的作用、数组容量的选择、Put方法的流程以及并发问题下的操作。文章还提到了扩容死链和数据错乱的问题,并探讨了key的设计要求。对于对Java面试中的HashMap问题感兴趣的读者,本文将为您提供一些有用的技术和经验。 ... [详细]
  • 本文讨论了在使用Git进行版本控制时,如何提供类似CVS中自动增加版本号的功能。作者介绍了Git中的其他版本表示方式,如git describe命令,并提供了使用这些表示方式来确定文件更新情况的示例。此外,文章还介绍了启用$Id:$功能的方法,并讨论了一些开发者在使用Git时的需求和使用场景。 ... [详细]
  • 《2017年3月全国计算机等级考试二级C语言上机题库完全版》由会员分享,可在线阅读,更多相关《2017年3月全国计算机等级考试二级C语言上机题库完全版( ... [详细]
  • java io换行符_Java IO:为什么从stdin读取时,换行符的数字表示出现在控制台上?...
    只是为了更好地理解我在讲座中听到的内容(关于Java输入和输出流),我自己做了这个小程序:publicstaticvoidmain(String[]args)thro ... [详细]
author-avatar
小宇宇宙2502862273
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有