只有函数、类和模块这三种可以开辟自己的作用域
模块就是py文件
一、time模块
1、在Python中,有三种方式来表示时间,分别是:
(1)时间戳:时间戳表示的是从1970年1月1日00:00:00开始按秒计算至现在的时间,时间戳是用来给计算机识别的
例如:
import time#调入时间模块 print(time.time())#获取时间戳执行结果是:
1493193792.014543(2)元组(struct_time)(结构化时间):struct_time元组共有9个元素共九个元素:(年,月,日,时,分,秒,一年中第几周,一年中第几天等)
示例:
#结构化时间 import time#调入时间模块 c=time.localtime() print(c)#这些返回的是属性,可以用对象加点的方式去调用 print(c.tm_year)#用对象加点的方式去调用 print(c.tm_mon)#用对象加点的方式去调用执行结果是:
time.struct_time(tm_year=2017, tm_mon=4, tm_mday=26, tm_hour=16, tm_min=9, tm_sec=11, tm_wday=2, tm_yday=116, tm_isdst=0) 2017 4(3)格式化的时间字符串:是用来显示人能看懂的时间,例如:“1990-10-10”
示例:
# 格式化的时间字符串:是用来显示人能看懂的时间 import time#调入时间模块 print(time.strftime("%Y-%m-%d %X"))#查看现在的时间执行结果是:
2017-04-26 16:14:06总结:
时间戳是计算机能够识别的时间;
时间字符串是人能够看懂的时间;
元组则是用来操作时间的
2、几种时间形式的转换
三者的转换关系如下图:(注:时间戳和字符串时间不能直接转换)
(1)结构化时间和时间戳之间的转换:
示例:
#一 时间戳<---->结构化时间: import time #时间戳转换成结构化时间localtime/gmtime print(time.localtime(60*60*24))#东八区时间 print(time.gmtime(60*60*24))#美国格林尼治时间 #结构化时间转换成时间戳mktime print(time.mktime(time.localtime()))执行结果是:
time.struct_time(tm_year=1970, tm_mon=1, tm_mday=2, tm_hour=8, tm_min=0, tm_sec=0, tm_wday=4, tm_yday=2, tm_isdst=0) time.struct_time(tm_year=1970, tm_mon=1, tm_mday=2, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=4, tm_yday=2, tm_isdst=0) 1493195686.0(2)结构化时间和字符串时间之间的转换:
示例:
#字符串时间<---->结构化时间: import time # 结构化时间转换成字符串时间:strptime print(time.strftime("%Y-%m-%d %X")) # 字符串时间转换成结构化时间:strftime print(time.strptime("2017-03-16 14:22:33","%Y-%m-%d %X"))执行结果是:
2017-04-26 16:46:42 time.struct_time(tm_year=2017, tm_mon=3, tm_mday=16, tm_hour=14, tm_min=22, tm_sec=33, tm_wday=3, tm_yday=75, tm_isdst=-1)
(3)由于时间戳和字符串之间不能直接转换,所以他们之间的转换需要通过结构化
转换关系如下图:
示例:
#字符串时间<---->时间戳 import time print(time.asctime(time.localtime()))#当前时间 print(time.asctime(time.localtime(11111111))) print(time.ctime(2222222))执行结果是:
Wed Apr 26 16:55:40 2017 Sat May 9 22:25:11 1970 Tue Jan 27 01:17:02 1970
二 、random模块(随机数模块)
import random
(1)示例:
import random#导入模块 print(random.random())#括号里面不能定义,取大于0小于1的随机数 print(random.randint(1,4)) #取[1,4]的随机数 print(random.randrange(1,3)) #取[1,3)的随机数 print(random.choice([11,26,3,4]))#在列表内随机取1个值 print(random.sample([11,26,3,4],2))#在列表内随机取2个值 print(random.uniform(1,3))#取大于1小于3的随机数 l=[1,2,34,53] random.shuffle(l)#打乱次序 print(l)执行结果是:
0.5944160367093295 3 2 3 [26, 4] 2.464739645781895 [34, 1, 53, 2](2)相关练习
要求:将范围(0,9)内的数与ASCII内对应的A-Z组合成5个字符串的随机组合
def validate(): s="" for i in range(5): rNum=random.randint(0,9)#取[0,9)内的随机数 res=chr(random.randint(65,90))#将ASCII内A-Z对应的数字找到,输出字母赋值给X X=random.choice([str(rNum),res]) s+=X#加到空字符串内 return s#返回字符串 print(validate())#运行函数执行结果是:
FJA71#是随机的,每次结果不一样
三 、hashlib (摘要算法)
(1)hashlib (摘要算法)相关介绍
Python的hashlib提供了常见的摘要算法,如MD5,SHA1等等。
什么是摘要算法呢?摘要算法又称哈希算法、散列算法。它通过一个函数,把任意长度的数据转换为一个长度固定的数据串(通常用16进制的字符串表示)。
摘要算法就是通过摘要函数f()对任意长度的数据data计算出固定长度的摘要digest,目的是为了发现原始数据是否被人篡改过。
摘要算法之所以能指出数据是否被篡改过,就是因为摘要函数是一个单向函数,计算f(data)很容易,但通过digest反推data却非常困难。而且,对原始数据做一个bit的修改,都会导致计算出的摘要完全不同。
我们以常见的摘要算法MD5为例,计算出一个字符串的MD5值:
示例:
import hashlib#调用模块 m=hashlib.md5() m.update("xuyuanyuan".encode("utf8")) #0638073fa20fe729b6182c17fc121e24 print(m.hexdigest())执行结果是:
0638073fa20fe729b6182c17fc121e24如果数据量很大,可以分块多次调用update(),最后计算的结果是一样的:
示例:
import hashlib#调用模块 m=hashlib.md5() m.update("xuyuanyuan".encode("utf8")) m.update("tom".encode("utf8")) print(m.hexdigest())执行结果是:
4a6a40e0d7644b3b38d0f2a3c693c312MD5是最常见的摘要算法,速度很快,生成结果是固定的128 bit字节,通常用一个32位的16进制字符串表示。另一种常见的摘要算法是SHA1,调用SHA1和调用MD5完全类似:
示例:
import hashlib sha1 = hashlib.sha1() sha1.update("xuyuanyuan".encode("utf8")) sha1.update("tom".encode("utf8")) print(sha1.hexdigest())执行结果是:
c8cf96e5bf1c0c7dc22ec1f6ec4dceb16d30fe57SHA1的结果是160 bit字节,通常用一个40位的16进制字符串表示。比SHA1更安全的算法是SHA256和SHA512,不过越安全的算法越慢,而且摘要长度更长。
(2)hashlib (摘要算法)的相关应用
任何允许用户登录的网站都会存储用户登录的用户名和口令。如何存储用户名和口令呢?方法是存到数据库表中:
name | password --------+---------- michael | 123456 bob | abc999 alice | alice2008如果以明文保存用户口令,如果数据库泄露,所有用户的口令就落入黑客的手里。此外,网站运维人员是可以访问数据库的,也就是能获取到所有用户的口令。正确的保存口令的方式是不存储用户的明文口令,而是存储用户口令的摘要,比如MD5:
username | password ---------+--------------------------------- michael | e10adc3949ba59abbe56e057f20f883e bob | 878ef96e86145580c38c87f0410ad153 alice | 99b1c2188db85afee403b1536010c2c9考虑这么个情况,很多用户喜欢用123456,888888,password这些简单的口令,于是,黑客可以事先计算出这些常用口令的MD5值,得到一个反推表:
'e10adc3949ba59abbe56e057f20f883e': '123456' '21218cca77804d2ba1922c33e0151105': '888888' '5f4dcc3b5aa765d61d8327deb882cf99': 'password'这样,无需破解,只需要对比数据库的MD5,黑客就获得了使用常用口令的用户账号。
对于用户来讲,当然不要使用过于简单的口令。但是,我们能否在程序设计上对简单口令加强保护呢?
由于常用口令的MD5值很容易被计算出来,所以,要确保存储的用户口令不是那些已经被计算出来的常用口令的MD5,这一方法通过对原始口令加一个复杂字符串来实现,俗称“加盐”:
hashlib.md5("salt".encode("utf8"))经过Salt处理的MD5口令,只要Salt不被黑客知道,即使用户输入简单口令,也很难通过MD5反推明文口令。
但是如果有两个用户都使用了相同的简单口令比如123456,在数据库中,将存储两条相同的MD5值,这说明这两个用户的口令是一样的。有没有办法让使用相同口令的用户存储不同的MD5呢?
如果假定用户无法修改登录名,就可以通过把登录名作为Salt的一部分来计算MD5,从而实现相同口令的用户也存储不同的MD5。
摘要算法在很多地方都有广泛的应用。要注意摘要算法不是加密算法,不能用于加密(因为无法通过摘要反推明文),只能用于防篡改,但是它的单向计算特性决定了可以在不存储明文口令的情况下验证用户口令。
四、 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") 重命名文件/目录 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的大小 '''
五 sys模块
主要是和python解释器打交道
import sys
import sys sys.argv 命令行参数List,第一个元素是程序本身路径 sys.exit(n) 退出程序,正常退出时exit(0) sys.version 获取Python解释程序的版本信息 sys.maxint 最大的Int值 sys.path 返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值 sys.platform 返回操作系统平台名称
六 logging模块
logging模块,日志模块
import logging
示例:
import logging # debug info warning(默认) error critical logging.debug('debug') logging.info('info') logging.warning('warning') # logging.error('error') logging.critical('critical') #默认的顺序是由上至下的,当五个全部执行时,warning以上的存入文件,显示warning以下的打印显示出来执行结果是:(将warning以下的打印显示出来)
WARNING:root:warning ERROR:root:error CRITICAL:root:critical默认情况下Python的logging模块将日志打印到了标准输出中,且只显示了大于等于WARNING级别的日志,这说明默认的日志级别设置为WARNING(日志级别等级CRITICAL > ERROR > WARNING > INFO > DEBUG),默认的日志格式为日志级别:Logger名称:用户输出消息。
有两种配置方式:
(1)confing函数
(2)logger对象
灵活配置日志级别,日志格式,输出位置:、
示例:(1)confing函数
#1 congfig函数("吸") import logging logging.basicConfig(level=logging.DEBUG,#从logging.debug开始全部存入文件 format="%(asctime)s [%(lineno)s] %(message)s",#指定handler使用的日志显示格式。 datefmt="%Y-%m-%d %H:%M:%S",#时间格式 filename="logger",#文件名 filemode="a"#文件的存入方式是追加进去 ) logging.debug('debug message') num=1000 logging.info('cost %s'%num) logging.warning('warning messagegfdsgsdfg') # logging.error('error message') logging.critical('critical message')执行结果是:
在文件logger内
2017-05-01 16:13:50 [24] debug message 2017-05-01 16:13:50 [26] cost 1000 2017-05-01 16:13:50 [27] warning messagegfdsgsdfg 2017-05-01 16:13:50 [28] error message 2017-05-01 16:13:50 [29] critical message相关的配置参数:
logging.basicConfig()函数中可通过具体参数来更改logging模块默认行为,可用参数有: filename:用指定的文件名创建FiledHandler,这样日志会被存储在指定的文件中。 filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。 format:指定handler使用的日志显示格式。 datefmt:指定日期时间格式。 level:设置rootlogger(后边会讲解具体概念)的日志级别 stream:用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件(f=open(‘test.log’,’w’)),默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。 format参数中可能用到的格式化串: %(name)s Logger的名字 %(levelno)s 数字形式的日志级别 %(levelname)s 文本形式的日志级别 %(pathname)s 调用日志输出函数的模块的完整路径名,可能没有 %(filename)s 调用日志输出函数的模块的文件名 %(module)s 调用日志输出函数的模块名 %(funcName)s 调用日志输出函数的函数名 %(lineno)d 调用日志输出函数的语句所在的代码行 %(created)f 当前时间,用UNIX标准的表示时间的浮 点数表示 %(relativeCreated)d 输出日志信息时的,自Logger创建以 来的毫秒数 %(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒 %(thread)d 线程ID。可能没有 %(threadName)s 线程名。可能没有 %(process)d 进程ID。可能没有 %(message)s用户输出的消息
示例:(2)logger对象
# 2 logger对象#是由logger=logging.getLogger() import logging def get_logger():#定义函数(既可以写入文件内部,也可以打印显示在屏幕上 logger=logging.getLogger() fh=logging.FileHandler("logger2")# 创建一个handler,用于写入日志文件 sh=logging.StreamHandler()# 再创建一个handler,用于输出到显示屏幕上 logger.setLevel(logging.DEBUG) #设定输出等级 fm=logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") logger.addHandler(fh) logger.addHandler(sh) fh.setFormatter(fm) sh.setFormatter(fm) return logger Logger=get_logger() Logger.debug('logger debug message') Logger.info('logger info message') Logger.warning('logger warning message') Logger.error('logger error message') Logger.critical('logger critical message')示例结果:(在文件里)
2017-05-01 16:26:24,511 - root - DEBUG - logger debug message 2017-05-01 16:26:24,511 - root - INFO - logger info message 2017-05-01 16:26:24,512 - root - WARNING - logger warning message 2017-05-01 16:26:24,512 - root - ERROR - logger error message 2017-05-01 16:26:24,512 - root - CRITICAL - logger critical message示例结果:(在屏幕上)
2017-05-01 16:26:24,511 - root - DEBUG - logger debug message 2017-05-01 16:26:24,511 - root - INFO - logger info message 2017-05-01 16:26:24,512 - root - WARNING - logger warning message 2017-05-01 16:26:24,512 - root - ERROR - logger error message 2017-05-01 16:26:24,512 - root - CRITICAL - logger critical messagelogging库提供了多个组件:Logger、Handler、Filter、Formatter。Logger对象提供应用程序可直接使用的接口,Handler发送日志到适当的目的地,Filter提供了过滤日志信息的方法,Formatter指定日志显示格式。另外,可以通过:logger.setLevel(logging.Debug)设置级别。
序列化模块主要是:
(1)json
(2)pikle
之前我们学习过用eval内置方法可以将一个字符串转成python对象,不过,eval方法是有局限性的,对于普通的数据类型,json.loads和eval都能用,但遇到特殊类型的时候,eval就不管用了,所以eval的重点还是通常用来执行一个字符串表达式,并返回表达式的值。
什么是序列化:
我们把对象(变量)从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling,在其他语言中也被称之为serialization,marshalling,flattening等等,都是一个意思。序列化之后,就可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器上。反过来,把变量内容从序列化的对象重新读到内存里称之为反序列化,即unpickling。
如果我们要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式,比如XML,但更好的方法是序列化为JSON,因为JSON表示出来就是一个字符串,可以被所有语言读取,也可以方便地存储到磁盘或者通过网络传输。JSON不仅是标准格式,并且比XML更快,而且可以直接在Web页面中读取,非常方便。
JSON表示的对象就是标准的JavaScript语言的对象一个子集,JSON和Python内置的数据类型对应如下:
import json i=10 s='hello' t=(1,4,6) l=[3,5,7] d={'name':"yuan"} json_str1=json.dumps(i) json_str2=json.dumps(s) json_str3=json.dumps(t) json_str4=json.dumps(l) json_str5=json.dumps(d) print(json_str1) #'10' print(json_str2) #'"hello"' print(json_str3) #'[1, 4, 6]' print(json_str4) #'[3, 5, 7]' print(json_str5) #'{"name": "yuan"}'
示例表达序列化1:
#序列化 import json d={"name":"xuyuanyuan","age":18} s=json.dumps(d)#将字典d转换成json字符串 print(s)执行结果是:
{"name": "xuyuanyuan", "age": 18}示例表达序列化2:
#序列化2 import json d={"name":"xuyuanyuan","age":18} f=open("new2",'w') #d指的是对象,f指的是内容流向哪里 json.dump(d,f)#---------1 转成json字符串 2 将json字符串写入f里(即文件new2中) f.close()
执行结果(在文件new2中):
{"name": "xuyuanyuan", "age": 18}
示例表达反序列化:
#反序列化 # 先建一个文件a.txt,写入内容{"name": "xuyuanyuan", "age": 18} import json f=open("a.txt","r") data=f.read() res=json.loads(data)#将字符串转化成字典---反序列化 print(res["name"])执行结果是:
xuyuanyuan
import pickle
和json一样,可以处理任意的数据类型,尽量都使用json,不建议使用pickle
##----------------------------序列化 import pickle dic={'name':'alvin','age':23,'sex':'male'} print(type(dic))#<class 'dict'> j=pickle.dumps(dic) print(type(j))#<class 'bytes'> f=open('序列化对象_pickle','wb')#注意是w是写入str,wb是写入bytes,j是'bytes' f.write(j) #-------------------等价于pickle.dump(dic,f) f.close() #-------------------------反序列化 import pickle f=open('序列化对象_pickle','rb') data=pickle.loads(f.read())# 等价于data=pickle.load(f) print(data['age'])
转载于:https://www.cnblogs.com/xuyuanyuan123/p/6769825.html