zoukankan      html  css  js  c++  java
  • 模块

    一.时间time模块:
    时间模块有3种形式:

    1.时间戳:time.time( )   按秒计算,从1970年开始到现在走过的秒数

    2.时间字符串:time.strftime( )   按某种自己定义的格式输出时间

    3.结构化时间:time.structime( )

    结构化的时间(struct_time):struct_time元组共有9个元素共九个元素:(年,月,日,时,分,秒,一年中第几周,一年中第几天,夏令时)

    对应的是:(tm_year=2017, tm_mon=12, tm_mday=14, tm_hour=23,

    tm_min=54, tm_sec=13, tm_wday=3, tm_yday=348, tm_isdst=0)

    import time
    print(time.time())
    print(time.strftime('%Y-%m-%d %X'))
    print(time.localtime())
    print(time.gmtime())
    # 时间戳,字符串格式时间,结构化的时间的之间的转换
    print(time.localtime(12121212212))
    print(time.mktime(time.localtime(12122121212)))
    print(time.strftime('%Y-%m-%d %X',time.localtime()))
    print(time.strptime('2012-12-12 12:12:05','%Y-%m-%d %X'))
    print(time.ctime())
    print(time.asctime(time.localtime()))
    >>>>>>>>>>
    1513266853.1306016
    2017-12-14 23:54:13
    time.struct_time(tm_year=2017, tm_mon=12, tm_mday=14, tm_hour=23, tm_min=54, tm_sec=13, tm_wday=3, tm_yday=348, tm_isdst=0)
    time.struct_time(tm_year=2017, tm_mon=12, tm_mday=14, tm_hour=15, tm_min=54, tm_sec=13, tm_wday=3, tm_yday=348, tm_isdst=0)
    time.struct_time(tm_year=2354, tm_mon=2, tm_mday=9, tm_hour=3, tm_min=23, tm_sec=32, tm_wday=1, tm_yday=40, tm_isdst=0)
    12122121212.0
    2017-12-14 23:54:13
    time.struct_time(tm_year=2012, tm_mon=12, tm_mday=12, tm_hour=12, tm_min=12, tm_sec=5, tm_wday=2, tm_yday=347, tm_isdst=-1)
    Thu Dec 14 23:54:13 2017
    Thu Dec 14 23:54:13 2017
    

    二.随机数模块 random  

    import random
     
    print(random.random())#(0,1)----float    大于0且小于1之间的小数
     
    print(random.randint(1,3))  #[1,3]    大于等于1且小于等于3之间的整数
     
    print(random.randrange(1,3)) #[1,3)    大于等于1且小于3之间的整数
     
    print(random.choice([1,'23',[4,5]]))#1或者23或者[4,5]
     
    print(random.sample([1,'23',[4,5]],2))#列表元素任意2个组合
     
    print(random.uniform(1,3))#大于1小于3的小数,如1.927109612082716 
     
     
    item=[1,3,5,7,9]
    random.shuffle(item) #打乱item的顺序,相当于"洗牌"
    print(item)
    
    随机验证码:
    1
    import random
    2 def check_code(): 3 s = '' 4 for i in range(5): 5 rNum = random.randint(0,9) 6 R_alpha = chr(random.randint(65,90)) 7 r_alpha = chr(random.randint(97,122)) 8 res = random.choice([str(rNum),r_alpha,R_alpha]) 9 s += res 10 return s 11 print(check_code())

     三.摘要算法 hashlib 模块

    摘要算法的特点:hash:一种算法 ,3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法
    三个特点:
    1.内容相同则hash运算结果相同,内容稍微改变则hash值则变
    2.不可逆推
    3.相同算法:无论校验多长的数据,得到的哈希值长度固定。

    1.md5算法:
    import hashlib
    m = hashlib.md5()
    m.update('wuzetian'.encode('utf-8'))
    print(m.hexdigest())
    >>>>>>>>>
    33b751484e6abe814c1b5834118a44d3
    
    
    
    2.hmac算法:
    import hmac
    h = hmac.new(b'yuan')     #对数据类型定义相同的key,无论进行多少次迭代摘要,得到的数据字符串都是
    h.update(b'hello')               相同的
    h.update(b'world')
    print(h.hexdigest())
     
    h1 = hmac.new(b'yuan') #key与h相同
    h1.update(b'helloworld')
    print(h1.hexdigest())
    h2 = hmac.new(b'yuanhelloworld')   #key与h h1都不同
    print(h2.hexdigest())
    >>>>>>>>>>>>>
    cb4c5d67ddba310cdb31731905f73c52
    cb4c5d67ddba310cdb31731905f73c52
    7fe9e01174e0022f06b578d6822dd7e9
    

    四.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下为"	
    ",Linux下为"
    "
    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的大小
    
    在Linux和Mac平台上,该函数会原样返回path,在windows平台上会将路径中所有字符转换为小写,并将所有斜杠转换为饭斜杠。
    >>> os.path.normcase('c:/windows\system32\')   
    'c:\windows\system32\'   
       
    
    规范化路径,如..和/
    >>> os.path.normpath('c://windows\System32\../Temp/')   
    'c:\windows\Temp'   
    
    >>> a='/Users/jieli/test1/\a1/\\aa.py/../..'
    >>> print(os.path.normpath(a))
    /Users/jieli/test1
    
    >>>>>>>>>>>>>>>>>>>>>>>>
    os路径处理
    #方式一:推荐使用
    import os
    #具体应用
    import os,sys
    possible_topdir = os.path.normpath(os.path.join(
        os.path.abspath(__file__),
        os.pardir, #上一级
        os.pardir,
        os.pardir
    ))
    sys.path.insert(0,possible_topdir)
    
    
    #方式二:不推荐使用
    os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
    

    五.sys模块  与解释器交互的一个模块

    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       返回操作系统平台名称
    
     1 #=========知识储备==========
     2 #进度条的效果
     3 [#             ]
     4 [##            ]
     5 [###           ]
     6 [####          ]
     7 
     8 #指定宽度
     9 print('[%-15s]' %'#')
    10 print('[%-15s]' %'##')
    11 print('[%-15s]' %'###')
    12 print('[%-15s]' %'####')
    13 
    14 #打印%
    15 print('%s%%' %(100)) #第二个%号代表取消第一个%的特殊意义
    16 
    17 #可传参来控制宽度
    18 print('[%%-%ds]' %50) #[%-50s]
    19 print(('[%%-%ds]' %50) %'#')
    20 print(('[%%-%ds]' %50) %'##')
    21 print(('[%%-%ds]' %50) %'###')
    22 
    23 
    24 #=========实现打印进度条函数==========
    25 import sys
    26 import time
    27 
    28 def progress(percent,width=50):
    29     if percent >= 1:
    30         percent=1
    31     show_str=('[%%-%ds]' %width) %(int(width*percent)*'#')
    32     print('
    %s %d%%' %(show_str,int(100*percent)),file=sys.stdout,flush=True,end='')
    33 
    34 
    35 #=========应用==========
    36 data_size=1025
    37 recv_size=0
    38 while recv_size < data_size:
    39     time.sleep(0.1) #模拟数据的传输延迟
    40     recv_size+=1024 #每次收1024
    41 
    42     percent=recv_size/data_size #接收的比例
    43     progress(percent,width=70) #进度条的宽度70
    44 
    45 打印进度条
    进度条

    六.logging模块   日志模块

    1.默认级别为warning,打印到终端

    import logging
    
    logging.debug('调试debug')
    logging.info('消息info')
    logging.warning('警告warn')
    logging.error('错误error')
    logging.critical('严重critical')
    
    '''
    WARNING:root:警告warn
    ERROR:root:错误error
    CRITICAL:root:严重critical
    '''
    

    2.为logging模块指定全局配置,针对所有logger有效,控制打印到文件中

    可在logging.basicConfig()函数中通过具体参数来更改logging模块默认行为,可用参数有
    filename:用指定的文件名创建FiledHandler(后边会具体讲解handler的概念),这样日志会被存储在指定的文件中。
    filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。
    format:指定handler使用的日志显示格式。 
    datefmt:指定日期时间格式。 
    level:设置rootlogger(后边会讲解具体概念)的日志级别 
    stream:用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件,默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。
    
    
    
    #格式
    %(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:用户输出的消息
    
     
    
    logging.basicConfig()
    
     1 #======介绍
     2 可在logging.basicConfig()函数中可通过具体参数来更改logging模块默认行为,可用参数有
     3 filename:用指定的文件名创建FiledHandler(后边会具体讲解handler的概念),这样日志会被存储在指定的文件中。
     4 filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。
     5 format:指定handler使用的日志显示格式。
     6 datefmt:指定日期时间格式。
     7 level:设置rootlogger(后边会讲解具体概念)的日志级别
     8 stream:用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件,默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。
     9 
    10 
    11 format参数中可能用到的格式化串:
    12 %(name)s Logger的名字
    13 %(levelno)s 数字形式的日志级别
    14 %(levelname)s 文本形式的日志级别
    15 %(pathname)s 调用日志输出函数的模块的完整路径名,可能没有
    16 %(filename)s 调用日志输出函数的模块的文件名
    17 %(module)s 调用日志输出函数的模块名
    18 %(funcName)s 调用日志输出函数的函数名
    19 %(lineno)d 调用日志输出函数的语句所在的代码行
    20 %(created)f 当前时间,用UNIX标准的表示时间的浮 点数表示
    21 %(relativeCreated)d 输出日志信息时的,自Logger创建以 来的毫秒数
    22 %(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
    23 %(thread)d 线程ID。可能没有
    24 %(threadName)s 线程名。可能没有
    25 %(process)d 进程ID。可能没有
    26 %(message)s用户输出的消息
    27 
    28 
    29 
    30 
    31 #========使用
    32 import logging
    33 logging.basicConfig(filename='access.log',
    34                     format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
    35                     datefmt='%Y-%m-%d %H:%M:%S %p',
    36                     level=10)
    37 
    38 logging.debug('调试debug')
    39 logging.info('消息info')
    40 logging.warning('警告warn')
    41 logging.error('错误error')
    42 logging.critical('严重critical')
    43 
    44 
    45 
    46 
    47 
    48 #========结果
    49 access.log内容:
    50 2017-07-28 20:32:17 PM - root - DEBUG -test:  调试debug
    51 2017-07-28 20:32:17 PM - root - INFO -test:  消息info
    52 2017-07-28 20:32:17 PM - root - WARNING -test:  警告warn
    53 2017-07-28 20:32:17 PM - root - ERROR -test:  错误error
    54 2017-07-28 20:32:17 PM - root - CRITICAL -test:  严重critical
    55 
    56 part2: 可以为logging模块指定模块级的配置,即所有logger的配置
    basicconfig配置日志

    3.logging模块的Formatter,logger,Handler,Filter对象:

    原理图:https://pan.baidu.com/s/1skWyTT7

    #logger:产生日志的对象
    
    #Filter:过滤日志的对象
    
    #Handler:接收日志然后控制打印到不同的地方,FileHandler用来打印到文件中,StreamHandler用来打印到终端
    
    #Formatter对象:可以定制不同的日志格式对象,然后绑定给不同的Handler对象使用,以此来控制不同的Handler的日志格式
    
     1 '''
     2 critical=50
     3 error =40
     4 warning =30
     5 info = 20
     6 debug =10
     7 '''
     8 
     9 
    10 import logging
    11 
    12 #1、logger对象:负责产生日志,然后交给Filter过滤,然后交给不同的Handler输出
    13 logger=logging.getLogger(__file__)
    14 
    15 #2、Filter对象:不常用,略
    16 
    17 #3、Handler对象:接收logger传来的日志,然后控制输出
    18 h1=logging.FileHandler('t1.log') #打印到文件
    19 h2=logging.FileHandler('t2.log') #打印到文件
    20 h3=logging.StreamHandler() #打印到终端
    21 
    22 #4、Formatter对象:日志格式
    23 formmater1=logging.Formatter('%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
    24                     datefmt='%Y-%m-%d %H:%M:%S %p',)
    25 
    26 formmater2=logging.Formatter('%(asctime)s :  %(message)s',
    27                     datefmt='%Y-%m-%d %H:%M:%S %p',)
    28 
    29 formmater3=logging.Formatter('%(name)s %(message)s',)
    30 
    31 
    32 #5、为Handler对象绑定格式
    33 h1.setFormatter(formmater1)
    34 h2.setFormatter(formmater2)
    35 h3.setFormatter(formmater3)
    36 
    37 #6、将Handler添加给logger并设置日志级别
    38 logger.addHandler(h1)
    39 logger.addHandler(h2)
    40 logger.addHandler(h3)
    41 logger.setLevel(10)
    42 
    43 #7、测试
    44 logger.debug('debug')
    45 logger.info('info')
    46 logger.warning('warning')
    47 logger.error('error')
    48 logger.critical('critical')
    View Code

    4.Handler与logger的级别

    logger是第一级过滤,然后才能到handler,我们可以给logger和handler同时设置level,但是需要注意的是

    Logger is also the first to filter the message based on a level — if you set the logger to INFO, and all handlers to DEBUG, you still won't receive DEBUG messages on handlers — they'll be rejected by the logger itself. If you set logger to DEBUG, but all handlers to INFO, you won't receive any DEBUG messages either — because while the logger says "ok, process this", the handlers reject it (DEBUG < INFO).
    
    
    
    #验证
    import logging
    
    
    form=logging.Formatter('%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
                        datefmt='%Y-%m-%d %H:%M:%S %p',)
    
    ch=logging.StreamHandler()
    
    ch.setFormatter(form)
    # ch.setLevel(10)
    ch.setLevel(20)
    
    l1=logging.getLogger('root')
    # l1.setLevel(20)
    l1.setLevel(10)
    l1.addHandler(ch)
    
    l1.debug('l1 debug')
    
    重要,重要,重要!!!
    

    5.应用

     1 """
     2 logging配置
     3 """
     4 
     5 import os
     6 import logging.config
     7 
     8 # 定义三种日志输出格式 开始
     9 
    10 standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' 
    11                   '[%(levelname)s][%(message)s]' #其中name为getlogger指定的名字
    12 
    13 simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
    14 
    15 id_simple_format = '[%(levelname)s][%(asctime)s] %(message)s'
    16 
    17 # 定义日志输出格式 结束
    18 
    19 logfile_dir = os.path.dirname(os.path.abspath(__file__))  # log文件的目录
    20 
    21 logfile_name = 'all2.log'  # log文件名
    22 
    23 # 如果不存在定义的日志目录就创建一个
    24 if not os.path.isdir(logfile_dir):
    25     os.mkdir(logfile_dir)
    26 
    27 # log文件的全路径
    28 logfile_path = os.path.join(logfile_dir, logfile_name)
    29 
    30 # log配置字典
    31 LOGGING_DIC = {
    32     'version': 1,
    33     'disable_existing_loggers': False,
    34     'formatters': {
    35         'standard': {
    36             'format': standard_format
    37         },
    38         'simple': {
    39             'format': simple_format
    40         },
    41     },
    42     'filters': {},
    43     'handlers': {
    44         #打印到终端的日志
    45         'console': {
    46             'level': 'DEBUG',
    47             'class': 'logging.StreamHandler',  # 打印到屏幕
    48             'formatter': 'simple'
    49         },
    50         #打印到文件的日志,收集info及以上的日志
    51         'default': {
    52             'level': 'DEBUG',
    53             'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件
    54             'formatter': 'standard',
    55             'filename': logfile_path,  # 日志文件
    56             'maxBytes': 1024*1024*5,  # 日志大小 5M
    57             'backupCount': 5,
    58             'encoding': 'utf-8',  # 日志文件的编码,再也不用担心中文log乱码了
    59         },
    60     },
    61     'loggers': {
    62         #logging.getLogger(__name__)拿到的logger配置
    63         '': {
    64             'handlers': ['default', 'console'],  # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
    65             'level': 'DEBUG',
    66             'propagate': True,  # 向上(更高level的logger)传递
    67         },
    68     },
    69 }
    70 
    71 
    72 def load_my_logging_cfg():
    73     logging.config.dictConfig(LOGGING_DIC)  # 导入上面定义的logging配置
    74     logger = logging.getLogger(__name__)  # 生成一个log实例
    75     logger.info('It works!')  # 记录该文件的运行状态
    76 
    77 if __name__ == '__main__':
    78     load_my_logging_cfg()
    79 
    80 logging配置文件
    logging配置文件
     1 """
     2 MyLogging Test
     3 """
     4 
     5 import time
     6 import logging
     7 import my_logging  # 导入自定义的logging配置
     8 
     9 logger = logging.getLogger(__name__)  # 生成logger实例
    10 
    11 
    12 def demo():
    13     logger.debug("start range... time:{}".format(time.time()))
    14     logger.info("中文测试开始。。。")
    15     for i in range(10):
    16         logger.debug("i:{}".format(i))
    17         time.sleep(0.2)
    18     else:
    19         logger.debug("over range... time:{}".format(time.time()))
    20     logger.info("中文测试结束。。。")
    21 
    22 if __name__ == "__main__":
    23     my_logging.load_my_logging_cfg()  # 在你程序文件的入口加载自定义logging配置
    24     demo()
    25 
    26 使用
    使用
     1 注意注意注意:
     2 
     3 
     4 #1、有了上述方式我们的好处是:所有与logging模块有关的配置都写到字典中就可以了,更加清晰,方便管理
     5 
     6 
     7 #2、我们需要解决的问题是:
     8     1、从字典加载配置:logging.config.dictConfig(settings.LOGGING_DIC)
     9 
    10     2、拿到logger对象来产生日志
    11     logger对象都是配置到字典的loggers 键对应的子字典中的
    12     按照我们对logging模块的理解,要想获取某个东西都是通过名字,也就是key来获取的
    13     于是我们要获取不同的logger对象就是
    14     logger=logging.getLogger('loggers子字典的key名')
    15 
    16     
    17     但问题是:如果我们想要不同logger名的logger对象都共用一段配置,那么肯定不能在loggers子字典中定义n个key   
    18  'loggers': {    
    19         'l1': {
    20             'handlers': ['default', 'console'],  #
    21             'level': 'DEBUG',
    22             'propagate': True,  # 向上(更高level的logger)传递
    23         },
    24         'l2: {
    25             'handlers': ['default', 'console' ], 
    26             'level': 'DEBUG',
    27             'propagate': False,  # 向上(更高level的logger)传递
    28         },
    29         'l3': {
    30             'handlers': ['default', 'console'],  #
    31             'level': 'DEBUG',
    32             'propagate': True,  # 向上(更高level的logger)传递
    33         },
    34 
    35 }
    36 
    37     
    38 #我们的解决方式是,定义一个空的key
    39     'loggers': {
    40         '': {
    41             'handlers': ['default', 'console'], 
    42             'level': 'DEBUG',
    43             'propagate': True, 
    44         },
    45 
    46 }
    47 
    48 这样我们再取logger对象时
    49 logging.getLogger(__name__),不同的文件__name__不同,这保证了打印日志时标识信息不同,但是拿着该名字去loggers里找key名时却发现找不到,于是默认使用key=''的配置
    50 
    51 !!!关于如何拿到logger对象的详细解释!!!
    解释

    6.logger的继承(了解)

     1 import logging
     2 
     3 formatter=logging.Formatter('%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
     4                     datefmt='%Y-%m-%d %H:%M:%S %p',)
     5 
     6 ch=logging.StreamHandler()
     7 ch.setFormatter(formatter)
     8 
     9 
    10 logger1=logging.getLogger('root')
    11 logger2=logging.getLogger('root.child1')
    12 logger3=logging.getLogger('root.child1.child2')
    13 
    14 
    15 logger1.addHandler(ch)
    16 logger2.addHandler(ch)
    17 logger3.addHandler(ch)
    18 logger1.setLevel(10)
    19 logger2.setLevel(10)
    20 logger3.setLevel(10)
    21 
    22 logger1.debug('log1 debug')
    23 logger2.debug('log2 debug')
    24 logger3.debug('log3 debug')
    25 '''
    26 2017-07-28 22:22:05 PM - root - DEBUG -test:  log1 debug
    27 2017-07-28 22:22:05 PM - root.child1 - DEBUG -test:  log2 debug
    28 2017-07-28 22:22:05 PM - root.child1 - DEBUG -test:  log2 debug
    29 2017-07-28 22:22:05 PM - root.child1.child2 - DEBUG -test:  log3 debug
    30 2017-07-28 22:22:05 PM - root.child1.child2 - DEBUG -test:  log3 debug
    31 2017-07-28 22:22:05 PM - root.child1.child2 - DEBUG -test:  log3 debug
    32 '''
    View Code

     七.json模块,pickle模块,都是对数据进行序列化操作:

    之前我们学习过用eval内置方法可以将一个字符串转成python对象,不过,eval方法是有局限性的,对于普通的数据类型,json.loads和eval都能用,但遇到特殊类型的时候,eval就不管用了,所以eval的重点还是通常用来执行一个字符串表达式,并返回表达式的值。

    1 import json
    2 x="[null,true,false,1]"
    3 print(eval(x)) #报错,无法解析null类型,而json就可以
    4 print(json.loads(x)) 

     系列化的概念:把一个变量(对象)从内存中变成一个可储存和传输的过程称为序列化。

    为什么要序列化?

    1:持久保存状态

    需知一个软件/程序的执行就在处理一系列状态的变化,在编程语言中,'状态'会以各种各样有结构的数据类型(也可简单的理解为变量)的形式被保存在内存中。

    内存是无法永久保存数据的,当程序运行了一段时间,我们断电或者重启程序,内存中关于这个程序的之前一段时间的数据(有结构)都被清空了。

    在断电或重启程序之前将程序当前内存中所有的数据都保存下来(保存到文件中),以便于下次程序执行能够从文件中载入之前的数据,然后继续执行,这就是序列化。

    具体的来说,你玩使命召唤闯到了第13关,你保存游戏状态,关机走人,下次再玩,还能从上次的位置开始继续闯关。或如,虚拟机状态的挂起等。

    2:跨平台数据交互

    序列化之后,不仅可以把序列化后的内容写入磁盘,还可以通过网络传输到别的机器上,如果收发的双方约定好实用一种序列化的格式,那么便打破了平台/语言差异化带来的限制,实现了跨平台数据交互。

    反过来,把变量内容从序列化的对象重新读到内存里称之为反序列化,即unpickling。

    如何序列化之json和pickle:

    json

    如果我们要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式,比如XML,但更好的方法是序列化为JSON,因为JSON表示出来就是一个字符串,可以被所有语言读取,也可以方便地存储到磁盘或者通过网络传输。JSON不仅是标准格式,并且比XML更快,而且可以直接在Web页面中读取,非常方便。

    JSON表示的对象就是标准的JavaScript语言的对象,JSON和Python内置的数据类型对应如下:

    import json      
    d = {'name':'yuan','age':18,'phone':12333445111212215}
    print(type(d))
    d1 = json.dumps(d)  #序列化   转换为字符格式
    print(type(d1))
    f =open('a.txt','w')
    f.write(d1)
    f.close()
    
    d2=json.load(open('a.txt'))  #反序列化
    print(d2)
    
    s = '{"name":"iiiiiiii"}'    #只要满足json格式的数据,无需dump也可以用load反序列化出来
    f = open('a.txt','w')
    f.write(s)
    f.close()
    f = open('a.txt')
    d3 = json.loads(f.read())
    print(d3)
    >>>>>>>>>>
    <class 'dict'>
    <class 'str'>
    {'age': 18, 'name': 'yuan', 'phone': 12333445111212215}
    {'name': 'iiiiiiii'}
    

    pickle

      

    1.pickle模块也是序列化模块:

    与json的比较:优点:能够将任意格式的数据进行序列化,序列化的结果是转换成字节格式的数据

                            缺点:只能在python中的py文件之间进行序列,反序列化,而且python不同版本之间不兼容

    import pickle                 转换成字节格式
    l = [1,2,3,4,5]
    l1 = pickle.dumps(l)
    print(l1)
    f = open('b.txt','wb')
    f.write(l1)   #写入文件是不可见的数据格式,无法直接读取,必须反序列化才能看到数据内容
    f.close()
    f1= open('b.txt','rb')
    p = pickle.loads(f1.read())
    print(p)
    >>>>>>>>>>>>>>>>>.
    b'x80x03]qx00(Kx01Kx02Kx03Kx04Kx05e.'
    [1, 2, 3, 4, 5]
    

      

      

      

      

      

  • 相关阅读:
    白鸦:互联网就是社区,液态的社区
    「芭比娃娃.com」
    做几个经营「人」的小网站,速速卖给大公司?
    关于工作与生活来自前hp总裁孙振耀
    新网站上线,酷狗狗 www.coogogo.com
    中国地摊联盟群组
    discuz!nt论坛搬迁后出错,提示:对象名 'dnt_templates' 无效
    时光.旅人
    const和readonly
    html.partial的一个bug?
  • 原文地址:https://www.cnblogs.com/njzy-yuan/p/8040672.html
Copyright © 2011-2022 走看看