Python模块一
Posted RWBY
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python模块一相关的知识,希望对你有一定的参考价值。
logging模块
我们来说一下这个logging模块,这个模块的功能是记录我们软件的各种状态,你们现在和我一起找到红蜘蛛的那个图标,然后右键找一找是不是有个错误日志.其实每个软件都是有错误日志的,开发人员可以通过错误日志中的内容
对他的程序进行修改
我们先来看一下函数式简单配置
import logging
logging.debug(
\'debug message\'
)
logging.info(
\'info message\'
)
logging.warning(
\'warning message\'
)
logging.error(
\'error message\'
)
logging.critical(
\'critical message\'
)
默认情况下Python的logging模块将日志打印到了标准输出中,且只显示了大于等于WARNING级别的日志,这说明默认的日志级别设置为WARNING(日志级别等级CRITICAL > ERROR > WARNING > INFO > DEBUG),默认的日志格式为日志级别:Logger名称:用户输出消息。
我们自己用函数写的这个可以正常使用但是不够灵活,我们看看这个灵活的
灵活配置日志级别,日志格式,输出位置:
import logging
logging.basicConfig(level=logging.DEBUG,
format=
\'%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s\'
,
datefmt=
\'%a, %d %b %Y %H:%M:%S\'
,
filename=
\'/tmp/test.log\'
,
filemode=
\'w\'
)
logging.debug(
\'debug message\'
)
logging.info(
\'info message\'
)
logging.warning(
\'warning message\'
)
logging.error(
\'error message\'
)
logging.critical(
\'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用户输出的消息
logger对象配置
import logging
logger = logging.getLogger()
# 创建一个handler,用于写入日志文件
fh = logging.FileHandler(
\'test.log\'
,encoding=
\'utf-8\'
)
# 再创建一个handler,用于输出到控制台
ch = logging.StreamHandler()
formatter = logging.Formatter(
\'%(asctime)s - %(name)s - %(levelname)s - %(message)s\'
)
fh.setLevel(logging.DEBUG)
fh.setFormatter(formatter)
ch.setFormatter(formatter)
logger.addHandler(fh) #logger对象可以添加多个fh和ch对象
logger.addHandler(ch)
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\'
)
ogging库提供了多个组件:Logger、Handler、Filter、Formatter。Logger对象提供应用程序可直接使用的接口,Handler发送日志到适当的目的地,Filter提供了过滤日志信息的方法,Formatter指定日志显示格式。另外,可以通过:logger.setLevel(logging.Debug)设置级别,当然,也可以通过
fh.setLevel(logging.Debug)单对文件流设置某个级别。
序列化
我们今天学习下序列化,什么是序列化呢? 将原本的字典、列表等内容转换成一个字符串的过程就叫做序列化。
为什么要有序列化模块: 比如,我们在python代码中计算的一个数据需要给另外一段程序使用,那我们怎么给? 现在我们能想到的方法就是存在文件里,然后另一个python程序再从文件里读出来。 但是我们都知道,对于文件来说是没有字典这个概念的,所以我们只能将数据转换成字典放到文件中。 你一定会问,将字典转换成一个字符串很简单,就是str(dic)就可以办到了,为什么我们还要学习序列化模块呢? 没错序列化的过程就是从dic 变成str(dic)的过程。现在你可以通过str(dic),将一个名为dic的字典转换成一个字符串, 但是你要怎么把一个字符串转换成字典呢? 聪明的你肯定想到了eval(),如果我们将一个字符串类型的字典str_dic传给eval,就会得到一个返回的字典类型了。 eval()函数十分强大,但是eval是做什么的?e官方demo解释为:将字符串str当成有效的表达式来求值并返回计算结果。 BUT!强大的函数有代价。安全性是其最大的缺点。 想象一下,如果我们从文件中读出的不是一个数据结构,而是一句"删除文件"类似的破坏性语句,那么后果实在不堪设设想。 而使用eval就要担这个风险。 所以,我们并不推荐用eval方法来进行反序列化操作(将str转换成python中的数据结构)
序列化的目的
1、以某种存储形式使自定义对象持久化;
2、将对象从一个地方传递到另一个地方。
3、使程序更具维护性。
json
Json模块提供了四个功能:dumps、dump、loads、load
dumps 及 loads
import json
dic = {
\'k1\'
:
\'v1\'
,
\'k2\'
:
\'v2\'
,
\'k3\'
:
\'v3\'
}
str_dic = json.dumps(dic) #序列化:将一个字典转换成一个字符串
print(type(str_dic),str_dic) #<
class
\'str\'
> {
"k3"
:
"v3"
,
"k1"
:
"v1"
,
"k2"
:
"v2"
}
#注意,json转换完的字符串类型的字典中的字符串是由""表示的
dic2 = json.loads(str_dic) #反序列化:将一个字符串格式的字典转换成一个字典
#注意,要用json的loads功能处理的字符串类型的字典中的字符串必须由""表示
print(type(dic2),dic2) #<
class
\'dict\'
> {
\'k1\'
:
\'v1\'
,
\'k2\'
:
\'v2\'
,
\'k3\'
:
\'v3\'
}
list_dic = [1,[
\'a\'
,
\'b\'
,
\'c\'
],3,{
\'k1\'
:
\'v1\'
,
\'k2\'
:
\'v2\'
}]
str_dic = json.dumps(list_dic) #也可以处理嵌套的数据类型
print(type(str_dic),str_dic) #<
class
\'str\'
> [1, [
"a"
,
"b"
,
"c"
], 3, {
"k1"
:
"v1"
,
"k2"
:
"v2"
}]
list_dic2 = json.loads(str_dic)
print(type(list_dic2),list_dic2) #<
class
\'list\'
> [1, [
\'a\'
,
\'b\'
,
\'c\'
], 3, {
\'k1\'
:
\'v1\'
,
\'k2\'
:
\'v2\'
}]
dump 及 load
import json
f = open(
\'json_file\'
,
\'w\'
)
dic = {
\'k1\'
:
\'v1\'
,
\'k2\'
:
\'v2\'
,
\'k3\'
:
\'v3\'
}
json.dump(dic,f) #dump方法接收一个文件句柄,直接将字典转换成json字符串写入文件
f.close()
f = open(
\'json_file\'
)
dic2 = json.load(f) #load方法接收一个文件句柄,直接将文件中的json字符串转换成数据结构返回
f.close()
print(type(dic2),dic2)
其他参数说明
Serialize obj to a JSON formatted str.(字符串表示的json对象) Skipkeys:默认值是False,如果dict的keys内的数据不是python的基本类型(str,unicode,int,long,float,bool,None),设置为False时,就会报TypeError的错误。此时设置成True,则会跳过这类key ensure_ascii:,当它为True的时候,所有非ASCII码字符显示为\\uXXXX序列,只需在dump时将ensure_ascii设置为False即可,此时存入json的中文即可正常显示。) If check_circular is false, then the circular reference check for container types will be skipped and a circular reference will result in an OverflowError (or worse). If allow_nan is false, then it will be a ValueError to serialize out of range float values (nan, inf, -inf) in strict compliance of the JSON specification, instead of using the JavaScript equivalents (NaN, Infinity, -Infinity). indent:应该是一个非负的整型,如果是0就是顶格分行显示,如果为空就是一行最紧凑显示,否则会换行且按照indent的数值显示前面的空白分行显示,这样打印出来的json数据也叫pretty-printed json separators:分隔符,实际上是(item_separator, dict_separator)的一个元组,默认的就是(‘,’,’:’);这表示dictionary内keys之间用“,”隔开,而KEY和value之间用“:”隔开。 default(obj) is a function that should return a serializable version of obj or raise TypeError. The default simply raises TypeError. sort_keys:将数据根据keys的值进行排序。 To use a custom JSONEncoder subclass (e.g. one that overrides the .default() method to serialize additional types), specify it with the cls kwarg; otherwise JSONEncoder is used.
json格式化输出
import json
data = {
\'username\'
:[
\'李华\'
,
\'二愣子\'
],
\'sex\'
:
\'male\'
,
\'age\'
:16}
json_dic2 = json.dumps(data,sort_keys=True,indent=2,separators=(
\',\'
,
\':\'
),ensure_ascii=False)
print(json_dic2)
pickle模块
用于序列化的两个模块
json,用于字符串 和 python数据类型间进行转换 pickle,用于python特有的类型 和 python的数据类型间进行转换 pickle模块提供了四个功能:dumps、dump(序列化,存)、loads(反序列化,读)、load (不仅可以序列化字典,列表...可以把python中任意的数据类型序列化)pickle是python特有的模块.
import pickle
dic = {
\'k1\'
:
\'v1\'
,
\'k2\'
:
\'v2\'
,
\'k3\'
:
\'v3\'
}
str_dic = pickle.dumps(dic)
print(str_dic) #一串二进制内容
dic2 = pickle.loads(str_dic)
print(dic2) #字典
import time
struct_time = time.localtime(1000000000)
print(struct_time)
f = open(
\'pickle_file\'
,
\'wb\'
)
pickle.dump(struct_time,f)
f.close()
f = open(
\'pickle_file\'
,
\'rb\'
)
struct_time2 = pickle.load(f)
print(struct_time2.tm_year)
这时候机智的你又要说了,既然pickle如此强大,为什么还要学json呢? 这里我们要说明一下,json是一种所有的语言都可以识别的数据结构。 如果我们将一个字典或者序列化成了一个json存在文件里,那么java代码或者js代码也可以拿来用。 但是如果我们用pickle进行序列化,其他语言就不能读懂这是什么了~ 所以,如果你序列化的内容是列表或者字典,我们非常推荐你使用json模块 但如果出于某种原因你不得不序列化其他的数据类型,而未来你还会用python对这个数据进行反序列化的话,那么就可以使用pickle
总结:
json模块里的dumps是将python的数据结构转换成字符串,loads是将字符串类型转换成python的数据结构
json模块里的dump是将python的数据结构转换成字符串,然后存入到文件当中
json模块里的load是将文件中字符串类型转换成python的数据结构
pickle模块里的dumps是将python的数据结构转换成二进制的文件,loads是将二进制的文件转换成python的
数据结构
pickle模块里的dump是将python的数据结构转换成二进制然后存入到文件中
pickle模块里的load是将文件中的二进制文件转成python的数据结构
random 模块
random是一个随机数模块,我们一般用来生成一些没有规则的内容
获取0-1之间的随机小数
import random
print(random.random())
生成指定的数字内的随机小数怎么办??
import random
print(random.uniform(1,5))
整数怎么做到随机呢
import random
print(random.randint(1,5))
生成随机的奇数和偶数
import random
print(random.randrange(1,5,2)) #随机生成1-5的奇数
print(random.randrange(0,5,2)) #随机生成0-5的偶数
现在有一个列表 lst = [\'张开\',\'宝元\',\'佩奇\',\'太白\'],随机抽一个人出来
import random
lst = [
\'张开\'
,
\'宝元\'
,
\'佩奇\'
,
\'太白\'
]
print(random.choice(lst))
随机抽出两个来
import random
lst = [
\'张开\'
,
\'宝元\'
,
\'佩奇\'
,
\'太白\'
]
print(random.choices(lst,k=2))
随机出来的两个内容是有重复的,没有满足需求重新实现
import random
lst = [
\'张开\'
,
\'宝元\'
,
\'佩奇\'
,
\'太白\'
]
print(random.sample(lst,k=2))
给你一个列表你给我让他变成随机排序的
import random
lst = [1,2,3,4,5,6]
random.shuffle(lst)
print(lst)
以上是关于Python模块一的主要内容,如果未能解决你的问题,请参考以下文章