zoukankan      html  css  js  c++  java
  • Python之模块

    Python之模块

      时间模块:

      import time

      time模块有三种方式来表示时间:时间戳,元组,格式化的时间字符串。

     (1)时间戳(给计算机看的):timestamp通常来说,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量,运行type(time.time()),返回的是float类型。

     (2)格式化的时间字符串(给人看的):Format String "1988-03-16"

     (3)元组(结构化时间:可以操作时间的):struct_time 元组共有9个元素(年、月、日、时、分、秒、一年中第几周、一年中第几天)

     1 # <1> 时间戳
     2 
     3 >>> import time
     4 >>> time.time()      #--------------返回当前时间的时间戳
     5 
     6 1493136727.099066
     7 
     8 # <2> 时间字符串
     9 
    10 >>> time.strftime("%Y-%m-%d %X")
    11 '2017-04-26 00:32:18'
    12 
    13 # <3> 时间元组
    14 
    15 >>> time.localtime()
    16 time.struct_time(tm_year=2017, tm_mon=4, tm_mday=26,
    17                  tm_hour=0, tm_min=32, tm_sec=42, tm_wday=2,
    18                  tm_yday=116, tm_isdst=0)
    View Code

       小结:时间戳是计算机能够识别的时间;时间字符串是人能够看懂的时间;元组则是用来操作时间的

     1 #一 时间戳<---->结构化时间:  localtime/gmtime   mktime
     2 import time
     3 time.localtime(3600*24)
     4 time.gmtime(3600*24)
     5 
     6 time.mktime(time.localtime())
     7 
     8 
     9 ##字符串时间<---->结构化时间: strftime/strptime
    10 
    11 time.strftime("%Y-%m-%d %X", time.localtime())
    12 time.strptime("2017-03-16","%Y-%m-%d")
    View Code

    >>> time.asctime(time.localtime(312343423))
    'Sun Nov 25 10:03:43 1979'
    >>> time.ctime(312343423)
    'Sun Nov 25 10:03:43 1979'
    
    
    1 #--------------------------其他方法
    2 # sleep(secs)
    3 # 线程推迟指定的时间运行,单位为秒。

     

      random模块:

       random随机模块   

     1 import random
     2 random.random()      # 大于0且小于1之间的小数
     3 0.7664338663654585
     4 
     5 random.randint(1,5)  # 大于等于1且小于等于5之间的整数
     6 
     7 random.randrange(1,3) # 大于等于1且小于3之间的整数
     8 
     9 random.choice([1,'23',[4,5]])  # #1或者23或者[4,5]
    10 
    11 random.sample([1,'23',[4,5]],2) # #列表元素任意2个组合
    12 [[4, 5], '23']
    13 
    14 random.uniform(1,3) #大于1小于3的小数
    15 1.6270147180533838
    16 
    17 item=[1,3,5,7,9]
    18 random.shuffle(item) # 打乱次序
    19 item
    20 [5, 1, 3, 7, 9]
    21 random.shuffle(item)
    22 item
    23 [5, 9, 7, 1, 3]
    View Code

       练习:生成验证码

     1 import random
     2 
     3 def v_code():
     4 
     5     code = ''
     6     for i in range(5):
     7 
     8         num=random.randint(0,9)
     9         alf=chr(random.randint(65,90))
    10         add=random.choice([num,alf])
    11         code="".join([code,str(add)])
    12 
    13     return code
    14 
    15 print(v_code())
    View Code
     1 import random
     2 
     3 
     4 #print(random.random())
     5 
     6 #print(random.randint(1,4))  #[1,4]
     7 #print(random.randrange(1,3))  #[1,3)
     8 
     9 # print(random.choice([11,26,3,4]))
    10 # print(random.sample([11,26,3,4],2))
    11 
    12 #print(random.uniform(1,3))
    13 
    14 # item=[1,23,33]
    15 #
    16 # random.shuffle(item)
    17 # print(item)
    18 
    19 # a-z  A-Z
    20 
    21 
    22 def validate():
    23 
    24     s=""
    25     for i in range(5):
    26          rNum=random.randint(0,9)
    27          r_alph=chr(random.randint(65,90))
    28 
    29          ret=random.choice([str(rNum),r_alph])
    30          s+=ret
    31 
    32     return s
    33 
    34 print(validate())
    View Code

     

      hashiliib模块:

         Python的hashlib提供了常见的摘要算法,如MD5,SHA1等等。

        什么是摘要算法呢?摘要算法又称哈希算法、散列算法。它通过一个函数,把任意长度的数据转换为一个长度固定的数据串(通常用16进制的字符串表示)。

        摘要算法就是通过摘要函数f()对任意长度的数据data计算出固定长度的摘要digest,目的是为了发现原始数据是否被人篡改过。

        摘要算法之所以能指出数据是否被篡改过,就是因为摘要函数是一个单向函数,计算f(data)很容易,但通过digest反推data却非常困难。

      而且,对原始数据做一个bit的修改,都会导致计算出的摘要完全不同。

        我们以常见的摘要算法MD5为例,计算出一个字符串的MD5值:

    import hashlib
     
    md5 = hashlib.md5()
    md5.update('how to use md5 in python hashlib?')
    print md5.hexdigest()
    
    计算结果如下:
    d26a53750bc40b38b65a520292f69306

      如果数据量很大,可以分块多次调用update(),最后计算的结果是一样的:

    md5 = hashlib.md5()
    md5.update('how to use md5 in ')
    md5.update('python hashlib?')
    print md5.hexdigest()

      MD5是最常见的摘要算法,速度很快,生成结果是固定的128 bit字节,通常用一个32位的16进制字符串表示。另一种常见的摘要算法是SHA1,调用SHA1和调用MD5完全类似:

    import hashlib
     
    sha1 = hashlib.sha1()
    sha1.update('how to use sha1 in ')
    sha1.update('python hashlib?')
    print sha1.hexdigest()

      SHA1的结果是160 bit字节,通常用一个40位的16进制字符串表示。比SHA1更安全的算法是SHA256和SHA512,不过越安全的算法越慢,而且摘要长度更长。

     摘要算法应用:

      任何允许用户登录的网站都会存储用户登录的用户名和口令。如何存储用户名和口令呢?方法是存到数据库表中:

    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。

    摘要算法在很多地方都有广泛的应用。要注意摘要算法不是加密算法,不能用于加密(因为无法通过摘要反推明文),只能用于防篡改,但是它的单向计算特性决定了可以在不存储明文口令的情况下验证用户口令。

      练习:

    import hashlib
    
    m=hashlib.md5()
    
    m.update("alex".encode("utf8"))  #534b44a19bf18d20b71ecc4eb77c572f
    
    print(m.hexdigest())
    
    m.update("alex".encode("utf8"))  #alexalex
    
    print(m.hexdigest())
    
    n=hashlib.md5("salt".encode("utf8")) #加盐
    n.update(b"alexalex")
    print(n.hexdigest())
    
    # m=hashlib.sha1()

      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下为"	
    ",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的大小
    '''

      注意:

       os.stat('path/filename')  获取文件/目录信息
    stat 结构:
    
    st_mode: inode 保护模式
    st_ino: inode 节点号。
    st_dev: inode 驻留的设备。
    st_nlink: inode 的链接数。
    st_uid: 所有者的用户ID。
    st_gid: 所有者的组ID。
    st_size: 普通文件以字节为单位的大小;包含等待某些特殊文件的数据。
    st_atime: 上次访问的时间。
    st_mtime: 最后一次修改的时间。
    st_ctime: 由操作系统报告的"ctime"。在某些系统上(如Unix)是最新的元数据更改的时间,在其它系统上(如Windows)是创建时间(详细信息参见平台的文档)。

      练习:

    import os
    
    # print(os.getcwd())
    
    # f=open("test.txt","w")
    
    # os.chdir(r"C:UsersAdministratorPycharmProjectspy_fullstack_s4day32") # cd
    
    # f=open("test2.txt","w")
    # print(os.getcwd())
    
    #os.makedirs("aaaaa/bbb")
    #os.removedirs("aaaaa/bbb")
    
    #print(os.listdir(r"C:UsersAdministratorPycharmProjectspy_fullstack_s4day33"))
    
    # print(os.stat(r"C:UsersAdministratorPycharmProjectspy_fullstack_s4day33	est.txt"))
    
    
    # '''
    # os.stat_result(st_mode=33206, st_ino=10133099161702379, st_dev=3233102476, st_nlink=1, st_uid=0, st_gid=0, st_size=0, st_atime=1493176560, st_mtime=1493176614, st_ctime=1493176560)
    #
    # '''
    
    # "yuan"+os.sep+"image"
    
    #print(os.name)
    #print(os.system("dir"))
    
    # abs=os.path.abspath("test.txt")
    # print(os.path.basename(abs))
    # print(os.path.dirname(abs))
    
    s1=r"C:UsersAdministratorPycharmProjects"
    
    s2=r"py_fullstack_s4day33"
    
    #print(s1+os.sep+s2)
    
    ret=os.path.join(s1,s2)   # 推荐方式
    print(ret)

      sys模块:

    sys.argv           命令行参数List,第一个元素是程序本身路径
    sys.exit(n)        退出程序,正常退出时exit(0)
    sys.version        获取Python解释程序的版本信息
    sys.maxint         最大的Int值
    sys.path           返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
    sys.platform       返回操作系统平台名称
    回到顶部

      

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

      配置参数:

     1 logging.basicConfig()函数中可通过具体参数来更改logging模块默认行为,可用参数有:
     2 
     3 filename:用指定的文件名创建FiledHandler,这样日志会被存储在指定的文件中。
     4 filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。
     5 format:指定handler使用的日志显示格式。
     6 datefmt:指定日期时间格式。
     7 level:设置rootlogger(后边会讲解具体概念)的日志级别
     8 stream:用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件(f=open(‘test.log’,’w’)),默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。
     9 
    10 format参数中可能用到的格式化串:
    11 %(name)s Logger的名字
    12 %(levelno)s 数字形式的日志级别
    13 %(levelname)s 文本形式的日志级别
    14 %(pathname)s 调用日志输出函数的模块的完整路径名,可能没有
    15 %(filename)s 调用日志输出函数的模块的文件名
    16 %(module)s 调用日志输出函数的模块名
    17 %(funcName)s 调用日志输出函数的函数名
    18 %(lineno)d 调用日志输出函数的语句所在的代码行
    19 %(created)f 当前时间,用UNIX标准的表示时间的浮 点数表示
    20 %(relativeCreated)d 输出日志信息时的,自Logger创建以 来的毫秒数
    21 %(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
    22 %(thread)d 线程ID。可能没有
    23 %(threadName)s 线程名。可能没有
    24 %(process)d 进程ID。可能没有
    25 %(message)s用户输出的消息
    View Code

       logger对象配置:

    import logging
    
    logger = logging.getLogger()
    # 创建一个handler,用于写入日志文件
    fh = logging.FileHandler('test.log')
    
    # 再创建一个handler,用于输出到控制台
    ch = logging.StreamHandler()
    
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    
    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')

    logging库提供了多个组件:Logger、Handler、Filter、Formatter。Logger对象提供应用程序可直接使用的接口,Handler发送日志到适当的目的地,Filter提供了过滤日志信息的方法,Formatter指定日志显示格式。另外,可以通过:logger.setLevel(logging.Debug)设置级别,当然,也可以通过

    fh.setLevel(logging.Debug)单对文件流设置某个级别。

     1 import logging
     2 
     3 import logging
     4 
     5 #  debug  info  warning(默认) error critical
     6 
     7 #1  congfig函数
     8 
     9 # logging.basicConfig(level=logging.DEBUG,
    10 #                     format="%(asctime)s [%(lineno)s] %(message)s",
    11 #                     datefmt="%Y-%m-%d %H:%M:%S",
    12 #                     filename="logger",
    13 #                     filemode="a"
    14 #                     )
    15 
    16 # logging.debug('debug message')
    17 # num=1000
    18 # logging.info('cost %s'%num)
    19 
    20 # logging.warning('warning messagegfdsgsdfg') #
    21 #
    22 # logging.error('error message')
    23 #
    24 # logging.critical('critical message')
    25 
    26 
    27 #配置两种方式: 1  congfig   2 logger
    28 
    29 # 2 logger对象
    30 
    31 def get_logger():
    32 
    33     logger=logging.getLogger()
    34 
    35     fh=logging.FileHandler("logger2")
    36 
    37     sh=logging.StreamHandler()
    38 
    39     logger.setLevel(logging.DEBUG)  #设定输出等级
    40 
    41     fm=logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
    42 
    43     logger.addHandler(fh)
    44 
    45     logger.addHandler(sh)
    46 
    47     fh.setFormatter(fm)
    48     sh.setFormatter(fm)
    49 
    50     return logger
    51 
    52 Logger=get_logger()
    53 
    54 Logger.debug('logger debug message')
    55 Logger.info('logger info message')
    56 Logger.warning('logger warning message')
    57 Logger.error('logger error message')
    58 Logger.critical('logger critical message')
    View Code

      *****json序列化模块*****:

        dumps  # 将字典d转为json字符串---序列化 ,那倒是的unicode的数据。

          loads    #将json字符串反序列化成之间的类型

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

     1 #---转换类型
     2 
     3 d={"name":"yuan"}
     4 
     5 s=str(d)
     6 
     7 print(type(s))
     8 
     9 d2=eval(s)
    10 
    11 print(d2[1])
    12 
    13 with open("test") as f:
    14 
    15     for i in f :
    16 
    17         if type(eval(i.strip()))==dict:
    18             print(eval(i.strip())[1])
    19             
    20 # 计算
    21 
    22 print(eval("12*7+5-3"))
    View Code

       什么是序列化?

      我们把对象(变量)从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling,在其他语言中也被称之为serialization,marshalling,flattening等等,都是一个意思。序列化之后,就可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器上。反过来,把变量内容从序列化的对象重新读到内存里称之为反序列化,即unpickling。

        json模块: 

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

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

     1 import json
     2 i=10
     3 s='hello'
     4 t=(1,4,6)
     5 l=[3,5,7]
     6 d={'name':"yuan"}
     7 
     8 json_str1=json.dumps(i)
     9 json_str2=json.dumps(s)
    10 json_str3=json.dumps(t)
    11 json_str4=json.dumps(l)
    12 json_str5=json.dumps(d)
    13 
    14 print(json_str1)   #'10'
    15 print(json_str2)   #'"hello"'
    16 print(json_str3)   #'[1, 4, 6]'
    17 print(json_str4)   #'[3, 5, 7]'
    18 print(json_str5)   #'{"name": "yuan"}'
    View Code

    python在文本中的使用: 

     1 #----------------------------序列化
     2 import json
     3 
     4 dic={'name':'alvin','age':23,'sex':'male'}
     5 print(type(dic))#<class 'dict'>
     6 
     7 data=json.dumps(dic)
     8 print("type",type(data))#<class 'str'>
     9 print("data",data)
    10 
    11 
    12 f=open('序列化对象','w')
    13 f.write(data)  #-------------------等价于json.dump(dic,f)
    14 f.close()
    15 
    16 
    17 #-----------------------------反序列化<br>
    18 import json
    19 f=open('序列化对象')
    20 new_data=json.loads(f.read())#  等价于data=json.load(f)
    21 
    22 print(type(new_data))
    View Code

      pickle序列化模块:

        pickle是无法读的。无法读取内容。

     1 ##----------------------------序列化
     2 import pickle
     3  
     4 dic={'name':'alvin','age':23,'sex':'male'}
     5  
     6 print(type(dic))#<class 'dict'>
     7  
     8 j=pickle.dumps(dic)
     9 print(type(j))#<class 'bytes'>
    10  
    11  
    12 f=open('序列化对象_pickle','wb')#注意是w是写入str,wb是写入bytes,j是'bytes'
    13 f.write(j)  #-------------------等价于pickle.dump(dic,f)
    14  
    15 f.close()
    16 #-------------------------反序列化
    17 import pickle
    18 f=open('序列化对象_pickle','rb')
    19  
    20 data=pickle.loads(f.read())#  等价于data=pickle.load(f)
    21  
    22 print(data['age'])
    View Code

       shelve序列化模块:

         shelve模块比pickle模块简单,只有一个open函数,返回类似字典的对象,可读可写;key必须为字符串,而值可以是python所支持的数据类型 

     1 import shelve
     2   
     3 f = shelve.open(r'shelve.txt')
     4   
     5 # f['stu1_info']={'name':'alex','age':'18'}
     6 # f['stu2_info']={'name':'alvin','age':'20'}
     7 # f['school_info']={'website':'oldboyedu.com','city':'beijing'}
     8 #
     9 #
    10 # f.close()
    11   
    12 print(f.get('stu_info')['age'])
    View Code

      练习:   

      1 # d={"河北":["廊坊","保定"],"湖南":["长沙","韶山"]}
      2 #
      3 # s=str(d)
      4 # with open("data","w") as f:
      5 #     f.write(s)
      6 
      7 # with open("data") as f2:
      8 #     s2=f2.read()
      9 #     d2=eval(s2)
     10 #
     11 # print(d2["河北"]) # '{"河北":["廊坊","保定"],"湖南":["长沙","韶山"]}'
     12 
     13 # print(eval("12+34*34"))
     14 
     15 import json
     16 
     17 
     18 import json
     19 
     20 
     21 # i=10
     22 # s='hello'
     23 # t=(1,4,6)
     24 # l=[3,5,7]
     25 # d={'name':"yuan"}
     26 #
     27 # json_str1=json.dumps(i)
     28 # json_str2=json.dumps(s)
     29 # json_str3=json.dumps(t)
     30 # json_str4=json.dumps(l)
     31 # json_str5=json.dumps(d)
     32 #
     33 # print(json_str1)   #'10'
     34 # print(json_str2)   #'"hello"'
     35 # print(json_str3)   #'[1, 4, 6]'
     36 # print(json_str4)   #'[3, 5, 7]'
     37 # print(json_str5)   #'{"name": "yuan"}'
     38 
     39 
     40 
     41 # # d={"河北":["廊坊","保定"],"湖南":["长沙","韶山"]}
     42 #
     43 # d={'name':"egon"}
     44 #
     45 # # s=json.dumps(d)  # 将字典d转为json字符串---序列化 ,那倒是的unicode的数据
     46 # #
     47 # # print(type(s))
     48 # # print(s)
     49 # #
     50 # #
     51 # # f=open("new",'w')
     52 # #
     53 # # f.write(s)
     54 # #
     55 # # f.close()
     56 #
     57 # # -------------- dump方式
     58 #
     59 # # f=open("new2",'w')
     60 # # json.dump(d,f)#---------1 转成json字符串 2 将json字符串写入f里
     61 # #
     62 # # f.close()
     63 #
     64 #
     65 # #-----------------反序列化
     66 #
     67 # # f=open("new")
     68 # #
     69 # # data=f.read()
     70 # #
     71 # # data2=json.loads(data)
     72 # #
     73 # # print(data2["name"])
     74 
     75 
     76 #------练习
     77 
     78 # f=open("new3")
     79 # data=f.read()
     80 #
     81 # ret=json.loads(data)
     82 # # ret=[123]
     83 # print(type(ret[0]))
     84 
     85 
     86 
     87 #----------------------------------pickle--------------------
     88 
     89 
     90 import pickle
     91 
     92 
     93 import datetime
     94 
     95 t=datetime.datetime.now()
     96 
     97 
     98 # d={"data":t}
     99 
    100 # json.dump(d,open("new4","w"))
    101 
    102 #d={"name":"alvin"}
    103 
    104 # s=pickle.dumps(d)
    105 # print(s)
    106 # print(type(s))
    107 #
    108 # f=open('new5',"wb")
    109 #
    110 # f.write(s)
    111 # f.close()
    112 
    113 
    114 # f=open("new5","rb")
    115 #
    116 # data=pickle.loads(f.read())
    117 #
    118 # print(data)
    View Code

      

      ******re模块******:     

      就其本质而言,正则表达式(或 RE)是一种小型的、高度专业化的编程语言,(在Python中)它内嵌在Python中,并通过 re 模块实现。正则表达式模式被编译成一系列的字节码,然后由用 C 编写的匹配引擎执行。

    字符匹配(普通字符,元字符):

    1 普通字符:大多数字符和字母都会和自身匹配
                  >>> re.findall('alvin','yuanaleSxalexwupeiqi')
                          ['alvin'] 

    2 元字符:. ^ $ * + ? { } [ ] | ( )  

      元字符:

      . ^ $

    1 import re
    2 
    3 ret1=re.findall('李.','李爽
    alex
    李四
    egon
    alvin
    李二')
    4 
    5 ret2=re.findall('^李.','李爽
    alex
    李四
    egon
    alvin
    李二')
    6 
    7 ret3=re.findall('李.$','李爽
    alex
    李四
    egon
    alvin
    李二')
    View Code

      * + ? { }

     1 import re
     2 
     3 ret1=re.findall('李.*','李杰
    alex
    李莲英
    egon
    alvin
    李二棍子')
     4 ret2=re.findall('李.+','李杰
    alex
    李莲英
    egon
    alvin
    李二棍子')
     5 
     6 ret3=re.findall('(李.{1,2})
    ','李杰
    alex
    李莲英
    egon
    alvin
    李二棍子') # 设定优先级的原因
     7 
     8 # 匹配一个数字包括整型和浮点型
     9 ret4=re.findall('d+.?d*','12.45,34,0.05,109')
    10 
    11 print(ret4)
    View Code

      注意:前面的*,+,?等都是贪婪匹配,也就是尽可能匹配,后面加?号使其变成惰性匹配

    ret=re.findall('131d+?','1312312312')
    print(ret)  ['1312']

      转义符

      1、反斜杠后边跟元字符去除特殊功能,比如.

      2、反斜杠后边跟普通字符实现特殊功能,比如d

    1 d  匹配任何十进制数;      它相当于类 [0-9]。
    2 D  匹配任何非数字字符;    它相当于类 [^0-9]。
    3 s  匹配任何空白字符;      它相当于类 [ 	
    
    fv]。
    4 S  匹配任何非空白字符;    它相当于类 [^ 	
    
    fv]。
    5 w  匹配任何字母数字字符;   它相当于类 [a-zA-Z0-9_]。
    6 W  匹配任何非字母数字字符; 它相当于类 [^a-zA-Z0-9_]
    7   匹配一个特殊字符边界,比如空格 ,&,#等
    View Code

      让我们看一下的应用:

    ret=re.findall(r'I','I am LIST')
    print(ret)#['I']

      接下来我们试着匹配下“abcle”中的‘cl’:

     1 import re
     2 
     3 ret=re.findall('cl','abcle')
     4 print(ret)#[]
     5 
     6 ret=re.findall('c\l','abcle')
     7 print(ret)#[]
     8 
     9 ret=re.findall('c\\l','abcle')
    10 print(ret)#[]
    11 
    12 ret=re.findall(r'c\l','abcle')
    13 print(ret)#[]
    14 
    15 
    16 # 是特殊符号所以,'abce'前面需要加r
    17 ret=re.findall(r'c\b',r'abce')
    18 print(ret)#[]
    View Code

      分组 ()

    m = re.findall(r'(ad)+', 'add')
    print(m)
     
    ret=re.search('(?P<id>d{2})/(?P<name>w{3})','23/com')
    print(ret.group())#23/com
    print(ret.group('id'))#23

      元字符之|

    ret=re.search('(ab)|d','rabhdg8sd')
    print(ret.group())#ab

      字符集[]

     1 #--------------------------------------------字符集[]
     2 ret=re.findall('a[bc]d','acd')
     3 print(ret)#['acd']
     4  
     5 ret=re.findall('[a-z]','acd')
     6 print(ret)#['a', 'c', 'd']
     7  
     8 ret=re.findall('[.*+]','a.cd+')
     9 print(ret)#['.', '+']
    10  
    11 #在字符集里有功能的符号: - ^ 
    12  
    13 ret=re.findall('[1-9]','45dha3')
    14 print(ret)#['4', '5', '3']
    15  
    16 ret=re.findall('[^ab]','45bdha3')
    17 print(ret)#['4', '5', 'd', 'h', '3']
    18  
    19 ret=re.findall('[d]','45bdha3')
    20 print(ret)#['4', '5', '3']
    View Code

        贪婪匹配

     贪婪匹配:在满足匹配时,匹配尽可能长的字符串,默认情况下,采用贪婪匹配
    1 string pattern1 = @"a.*c";   // greedy match 
    2 Regex regex = new Regex(pattern1);
    3 regex.Match("abcabc"); // return "abcabc"
    4 非贪婪匹配:在满足匹配时,匹配尽可能短的字符串,使用?来表示非贪婪匹配
    5 
    6 string pattern1 = @"a.*?c";   // non-greedy match 
    7 Regex regex = new Regex(pattern1);
    8 regex.Match("abcabc"); // return "abc"
    View Code
     几个常用的非贪婪匹配Pattern
    *? 重复任意次,但尽可能少重复
    +? 重复1次或更多次,但尽可能少重复
    ?? 重复0次或1次,但尽可能少重复
    {n,m}? 重复n到m次,但尽可能少重复
    {n,}? 重复n次以上,但尽可能少重复
    .*?的用法:
    --------------------------------
    
    . 是任意字符
    * 是取 0 至 无限长度
    ? 是非贪婪模式。
    何在一起就是 取尽量少的任意字符,一般不会这么单独写,他大多用在:
    .*?x
    
    就是取前面任意长度的字符,直到一个x出现

          re模块下的常用方法

    
    
     1 import re
     2 
     3 re.findall('a','alvin yuan')    #返回所有满足匹配条件的结果,放在列表里
     4 
     5 re.search('a','alvin yuan').group()  
     6 
     7                #函数会在字符串内查找模式匹配,只到找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以
     8                # 通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None。
     9  
    10 
    11 
    12 re.match('a','abc').group()     #同search,不过尽在字符串开始处进行匹配
    13  
    14 
    15 ret=re.split('[ab]','abcd')     #先按'a'分割得到''和'bcd',在对''和'bcd'分别按'b'分割
    16 
    17 print(ret)#['', '', 'cd']
    18  
    19 
    20 ret=re.sub('d','abc','alvin5yuan6',1)
    21 
    22 ret=re.subn('d','abc','alvin5yuan6')
    23 
    24 
    25 obj=re.compile('d{3}')
    26 ret=obj.search('abc123eeee')
    27 print(ret.group())#123
    28 
    29 
    30 import re
    31 ret=re.finditer('d','ds3sy4784a')
    32 print(ret)        #<callable_iterator object at 0x10195f940>
    33  
    34 print(next(ret).group())
    35 print(next(ret).group())
    View Code
    
    

    注意:

    1 findall的优先级查询:

    1 import re
    2  
    3 ret=re.findall('www.(baidu|oldboy).com','www.oldboy.com')
    4 print(ret)#['oldboy']     这是因为findall会优先把匹配结果组里内容返回,如果想要匹配结果,取消权限即可
    5  
    6 ret=re.findall('www.(?:baidu|oldboy).com','www.oldboy.com')
    7 print(ret)#['www.oldboy.com']
    View Code

    2 split的优先级查询

    ret=re.split("d+","yuan2egon56alex")
    print(ret)
    
    ret=re.split("(d+)","yuan2egon56alex")
    print(ret)

    练习

    1、匹配标签

    1 import re
    2 
    3 print(re.findall("<(?P<tag_name>w+)>w+</(?P=tag_name)>","<h1>hello</h1>"))
    4 print(re.search("<(?P<tag_name>w+)>w+</(?P=tag_name)>","<h1>hello</h1>"))
    5 print(re.search(r"<(w+)>w+</1>","<h1>hello</h1>"))
    View Code 

    2、匹配整数 

    1 #匹配出所有的整数
    2 import re
    3 
    4 #ret=re.findall(r"d+{0}]","1-2*(60+(-40.35/5)-(-4*3))")
    5 ret=re.findall(r"-?d+.d*|(-?d+)","1-2*(60+(-40.35/5)-(-4*3))")
    6 ret.remove("")
    7 
    8 print(ret)
    View Code

    3、数字匹配 

     1 1、 匹配一段文本中的每行的邮箱
     2 
     3 2、 匹配一段文本中的每行的时间字符串,比如:‘1990-07-12’;
     4 
     5    分别取出1年的12个月(^(0?[1-9]|1[0-2])$)、
     6    一个月的31天:^((0?[1-9])|((1|2)[0-9])|30|31)$
     7 
     8 3、 匹配一段文本中所有的身份证数字。
     9 
    10 4、 匹配qq号。(腾讯QQ号从10000开始)  [1,9][0,9]{4,}
    11 
    12 5、 匹配一个浮点数。       ^(-?d+)(.d+)?$   或者  -?d+.?d*
    13 
    14 6、 匹配汉字。             ^[u4e00-u9fa5]{0,}$ 
    15 
    16 7、 匹配出所有整数
    View Code

    4、爬虫练习

     1 import requests
     2 
     3 import re
     4 import json
     5 
     6 def getPage(url):
     7 
     8     response=requests.get(url)
     9     return response.text
    10 
    11 def parsePage(s):
    12     
    13     com=re.compile('<div class="item">.*?<div class="pic">.*?<em .*?>(?P<id>d+).*?<span class="title">(?P<title>.*?)</span>'
    14                    '.*?<span class="rating_num" .*?>(?P<rating_num>.*?)</span>.*?<span>(?P<comment_num>.*?)评价</span>',re.S)
    15 
    16     ret=com.finditer(s)
    17     for i in ret:
    18         yield {
    19             "id":i.group("id"),
    20             "title":i.group("title"),
    21             "rating_num":i.group("rating_num"),
    22             "comment_num":i.group("comment_num"),
    23         }
    24 
    25 def main(num):
    26 
    27     url='https://movie.douban.com/top250?start=%s&filter='%num
    28     response_html=getPage(url)
    29     ret=parsePage(response_html)
    30     print(ret)
    31     f=open("move_info7","a",encoding="utf8")
    32 
    33     for obj in ret:
    34         print(obj)
    35         data=json.dumps(obj,ensure_ascii=False)
    36         f.write(data+"
    ")
    37 
    38 if __name__ == '__main__':
    39     count=0
    40     for i in range(10):
    41         main(count)
    42         count+=25
    View Code

    5、test

      1 # 正则:对字符串的模糊匹配
      2 
      3 # key:元字符(有特殊功能的字符)
      4 
      5 import re
      6 
      7 #   re.findall(pattern, string,) # 找到所有的匹配元素,返回列表
      8 
      9 #元字符介绍
     10 
     11 # . :匹配除
    以外的任意符号
     12 
     13 #print(re.findall("a.+d","abcd"))  
     14 
     15 
     16 # ^:从字符串开始位置匹配
     17 
     18 # $:从字符串结尾匹配
     19 
     20 # print(re.findall("^yuan","yuandashj342jhg234"))
     21 # print(re.findall("yuan$","yuandashj342jhg234yuan"))
     22 
     23 # * + ?  {} :重复
     24 
     25 #print(re.findall("[0-9]{4}","af5324jh523hgj34gkhg53453"))
     26 
     27 
     28 #贪婪匹配
     29 print(re.findall("d+","af5324jh523hgj34gkhg53453"))
     30 
     31 #非贪婪匹配
     32 
     33 # print(re.findall("d+?","af5324jh523hgj34gkhg53453"))
     34 # print(re.findall("(abcd)*?","af5324jh523hgj34gkhg53453"))
     35 
     36 # 字符集 []: 起一个或者的意思
     37 
     38 # print(re.findall("a[bc]d","hasdabdjhacd"))
     39 
     40 #注意: * ,+.等元字符都是普通符号, - ^ 
     41 
     42 # print(re.findall("[0-9]+","dashj342jhg234"))
     43 # print(re.findall("[a-z]+","dashj342jhg234"))
     44 #
     45 # print(re.findall("[^d]+","d2a2fhj87fgj"))
     46 
     47 
     48 # ():分组
     49 
     50 # print(re.findall("(ad)+","addd"))
     51 # print(re.findall("(ad)+yuan","adddyuangfsdui"))
     52 
     53 # print(re.findall("(?:ad)+yuan","adadyuangfsdui"))
     54 # print(re.findall("(?:d)+yuan","adad678423yuang4234fsdui"))
     55 
     56 #命名分组
     57 
     58 #ret8=re.search(r"(?P<A>w+)\aticles\(?P<id>d{4})",r"yuanaticles1234")
     59 #ret8=re.search(r"a\nb",r"a
    b")
     60 #print(ret8)
     61 
     62 # print(ret8.group("id"))
     63 # print(ret8.group("A"))
     64 
     65 
     66 # # |  :或
     67 #
     68 # print(re.findall("www.(?:oldboy|baidu).com","www.oldboy.com"))
     69 
     70 # :转义
     71 
     72 # 1 后面加一个元字符使其变成普通符号 .  *
     73 # 2 将一些普通符号变成特殊符号 比如 d w
     74 
     75 # print(re.findall("d+.?d**d+.?d*","-2*6+7*45+1.456*3-8/4"))
     76 # print(re.findall("w","$da@s4 234"))
     77 # print(re.findall("asb","a badf"))
     78 
     79 # print(re.findall("\bI","hello I am LIA"))
     80 # print(re.findall(r"dI","hello 654I am LIA"))
     81 
     82 # print(re.findall(r"c\l","abcl"))
     83 
     84 
     85 #  re的方法
     86 
     87 
     88 # re.findall()
     89 
     90 
     91 # s=re.finditer("d+","ad324das32")
     92 # print(s)
     93 #
     94 # print(next(s).group())
     95 # print(next(s).group())
     96 
     97 
     98 # "(3+7*2+27+7+(4/2+1))+3"
     99 
    100 # search;只匹配第一个结果
    101 
    102 # ret=re.search("d+","djksf34asd3")
    103 # print(ret.group())
    104 #
    105 # #match:只在字符串开始的位置匹配
    106 # ret=re.match("d+","423djksf34asd3")
    107 # print(ret.group())
    108 
    109 #split 分割
    110 # s2=re.split("d+","fhd3245jskf54skf453sd",2)
    111 # print(s2)
    112 #
    113 # ret3=re.split("l","hello yuan")
    114 # print(ret3)
    115 #
    116 # #sub: 替换
    117 #
    118 # ret4=re.sub("d+","A","hello 234jkhh23",1)
    119 # print(ret4)
    120 #
    121 # ret4=re.subn("d+","A","hello 234jkhh23")
    122 # print(ret4)
    123 
    124 
    125 #compile: 编译方法
    126 # c=re.compile("d+")
    127 #
    128 # ret5=c.findall("hello32world53") #== re.findall("d+","hello32world53")
    129 # print(ret5)
    130 
    131 
    132 #计算:"1 - 2 * ( (60-30*2+-96) - (-4*3)/ (16-3*2) )"
    133 
    134 # s1="1+-2++5"
    135 #
    136 # def addsub(s):
    137 #     pass
    138 #
    139 # def muldiv(s): #(60-30*2+-96)
    140 #     pass
    141 #     return (60-60+-96)
    142 #
    143 # def f(s):
    144 #     s.replace("+-","-")
    145 #
    146 #
    147 # while re.search("([^()]+)", s):
    148 #     res = re.search("([^()]+)", s) #(60-30*2+-96)
    149 #     res=muldiv(res)
    150 #     ret=addsub(res)
    151 # else:
    152 #     res = muldiv(res)
    153 #     ret = addsub(res)
    154 
    155 
    156 s="2"
    157 
    158 print(res.group())
    View Code

    作业:计算器

    扩展:

      1 logging模块
      2 import logging  
      3 logging.debug('debug message')  
      4 logging.info('info message')  
      5 logging.warning('warning message')  
      6 logging.error('error message')  
      7 logging.critical('critical message')
      8 
      9 运行结果:
     10 C:Python36python.exe C:/Users/Administrator/PycharmProjects/py_fullstack_s4/day34/test.py
     11 WARNING:root:warning message
     12 ERROR:root:error message
     13 CRITICAL:root:critical message
     14 可以看出有一个默认的等级:debug--info--warning(默认)--error--critical
     15 
     16 配置的两种方式:
     17 1、congfig函数
     18 import logging  
     19 logging.basicConfig(level=logging.DEBUG,  
     20                     format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',  
     21                     datefmt='%a, %d %b %Y %H:%M:%S',  
     22                     filename='/tmp/test.log',  
     23                     filemode='w')
     24 
     25 logging.debug('debug message')  
     26 logging.info('info message')  
     27 logging.warning('warning message')  
     28 logging.error('error message')  
     29 logging.critical('critical message')
     30 level表示日志等级,选择DEBUG的话会将所有的都打印出来,最重要的就是format的内容,具体的配置参数如下:
     31 
     32 可见在logging.basicConfig()函数中可通过具体参数来更改logging模块默认行为,可用参数有
     33 filename:用指定的文件名创建FiledHandler(后边会具体讲解handler的概念),这样日志会被存储在指定的文件中。
     34 filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。
     35 format:指定handler使用的日志显示格式。 
     36 datefmt:指定日期时间格式。 
     37 level:设置rootlogger(后边会讲解具体概念)的日志级别 
     38 stream:用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件(f=open('test.log','w')),默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。
     39 
     40 format参数中可能用到的格式化串:
     41 %(name)s Logger的名字
     42 %(levelno)s 数字形式的日志级别
     43 %(levelname)s 文本形式的日志级别
     44 %(pathname)s 调用日志输出函数的模块的完整路径名,可能没有
     45 %(filename)s 调用日志输出函数的模块的文件名
     46 %(module)s 调用日志输出函数的模块名
     47 %(funcName)s 调用日志输出函数的函数名
     48 %(lineno)d 调用日志输出函数的语句所在的代码行
     49 %(created)f 当前时间,用UNIX标准的表示时间的浮 点数表示
     50 %(relativeCreated)d 输出日志信息时的,自Logger创建以 来的毫秒数
     51 %(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
     52 %(thread)d 线程ID。可能没有
     53 %(threadName)s 线程名。可能没有
     54 %(process)d 进程ID。可能没有
     55 %(message)s用户输出的消息
     56 2、logger对象
     57 上述几个例子中我们了解到了logging.debug()、logging.info()、logging.warning()、logging.error()、logging.critical()(分别用以记录不同级别的日志信息),logging.basicConfig()(用默认日志格式(Formatter)为日志系统建立一个默认的流处理器(StreamHandler),设置基础配置(如日志级别等)并加到root logger(根Logger)中)这几个logging模块级别的函数,另外还有一个模块级别的函数是logging.getLogger([name])(返回一个logger对象,如果没有指定名字将返回root logger) 先看一个最简单的过程:
     58 
     59 import logging
     60 
     61 logger = logging.getLogger()
     62 # 创建一个handler,用于写入日志文件
     63 fh = logging.FileHandler('test.log')
     64 
     65 # 再创建一个handler,用于输出到控制台
     66 ch = logging.StreamHandler()
     67 
     68 formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
     69 
     70 fh.setFormatter(formatter)
     71 ch.setFormatter(formatter)
     72 
     73 logger.addHandler(fh) #logger对象可以添加多个fh和ch对象
     74 logger.addHandler(ch)
     75 
     76 logger.debug('logger debug message')
     77 logger.info('logger info message')
     78 logger.warning('logger warning message')
     79 logger.error('logger error message')
     80 logger.critical('logger critical message')
     81 
     82 运行结果:
     83 2017-04-27 09:19:56,145 - root - WARNING - logger warning message
     84 2017-04-27 09:19:56,146 - root - ERROR - logger error message
     85 2017-04-27 09:19:56,146 - root - CRITICAL - logger critical message
     86 先简单介绍一下,logging库提供了多个组件:Logger、Handler、Filter、Formatter。Logger对象提供应用程序可直接使用的接口,Handler发送日志到适当的目的地,Filter提供了过滤日志信息的方法,Formatter指定日志显示格式。
     87 
     88 Logger是一个树形层级结构,输出信息之前都要获得一个Logger(如果没有显示的获取则自动创建并使用root Logger,如第一个例子所示)。
     89 
     90 logger = logging.getLogger()返回一个默认的Logger也即root Logger,并应用默认的日志级别、Handler和Formatter设置。 当然也可以通过Logger.setLevel(lel)指定最低的日志级别,可用的日志级别有logging.DEBUG、logging.INFO、logging.WARNING、logging.ERROR、logging.CRITICAL。
     91 
     92 Logger.debug()、Logger.info()、Logger.warning()、Logger.error()、Logger.critical()输出不同级别的日志,只有日志等级大于或等于设置的日志级别的日志才会被输出。
     93 
     94 logger.debug('logger debug message')  
     95 logger.info('logger info message')  
     96 logger.warning('logger warning message')  
     97 logger.error('logger error message')  
     98 logger.critical('logger critical message') 
     99 只输出了
    100 
    101 2014-05-06 12:54:43,222 - root - WARNING - logger warning message
    102 2014-05-06 12:54:43,223 - root - ERROR - logger error message
    103 2014-05-06 12:54:43,224 - root - CRITICAL - logger critical message
    104 从这个输出可以看出logger = logging.getLogger()返回的Logger名为root。这里没有用logger.setLevel(logging.Debug)显示的为logger设置日志级别,所以使用默认的日志级别WARNIING,故结果只输出了大于等于WARNIING级别的信息。
    105 
    106 序列化模块(json、pickle)
    107 什么是序列化?
    108 我们把对象(变量)从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling,在其他语言中也被称之为serialization,marshalling,flattening等等,都是一个意思。
    109 
    110 序列化之后,就可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器上。
    111 
    112 反过来,把变量内容从序列化的对象重新读到内存里称之为反序列化,即unpickling。
    113 
    114 json模块
    115 如果我们要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式,比如XML,但更好的方法是序列化为JSON,因为JSON表示出来就是一个字符串,可以被所有语言读取,也可以方便地存储到磁盘或者通过网络传输。JSON不仅是标准格式,并且比XML更快,而且可以直接在Web页面中读取,非常方便。
    116 
    117 JSON表示的对象就是标准的JavaScript语言的对象,JSON和Python内置的数据类型对应如下:
    118 
    119 
    120 
    121 #----------------------------序列化
    122 
    123 import json
    124 
    125 dic={'name':'alvin','age':23,'sex':'male'}
    126 print(type(dic))#<class 'dict'>
    127 j=json.dumps(dic)
    128 print(type(j))#<class 'str'>
    129 f=open('序列化对象','w')
    130 f.write(j)  #-------------------等价于json.dump(dic,f)
    131 f.close()
    132 #-----------------------------反序列化<br>
    133 import json
    134 f=open('序列化对象')
    135 data=json.loads(f.read())#  等价于data=json.load(f)
    136 d = {'name':'alvin','age':23,'sex':'male'}
    137 
    138 f = open("filename",'w')
    139 
    140 json.dump(d,f) #与dumps的区别在于将两步合成一步
    141 
    142 f.close()
    143 
    144 pickle模块
    145 ##----------------------------序列化
    146 import pickle
    147 
    148 dic={'name':'alvin','age':23,'sex':'male'}
    149 print(type(dic))#<class 'dict'>
    150 j=pickle.dumps(dic)
    151 print(type(j))#<class 'bytes'>
    152 f=open('序列化对象_pickle','wb')#注意是w是写入str,wb是写入bytes,j是'bytes'
    153 f.write(j)  #-------------------等价于pickle.dump(dic,f
    154 f.close()
    155 #-------------------------反序列化
    156 import pickle
    157 f=open('序列化对象_pickle','rb')
    158 data=pickle.loads(f.read())#  等价于data=pickle.load(f)
    159 print(data['age'])  
    160 Pickle的问题和所有其他编程语言特有的序列化问题一样,就是它只能用于Python,并且可能不同版本的Python彼此都不兼容,因此,只能用Pickle保存那些不重要的数据,不能成功地反序列化也没关系。
    161 
    162 re模块
    163 就其本质而言,正则表达式(或 RE)是一种小型的、高度专业化的编程语言,(在Python中)它内嵌在Python中,并通过 re 模块实现。正则表达式模式被编译成一系列的字节码,然后由用 C 编写的匹配引擎执行。
    164 
    165 字符匹配(普通字符,元字符):
    166 
    167 1 普通字符:大多数字符和字母都会和自身匹配 >>> re.findall('alvin','yuanaleSxalexwupeiqi') ['alvin']
    168 
    169 2 元字符:. ^ $ * + ? { } [ ] | ( ) 
    170 
    171 re.findall("(?:ad)+yuan","adadyuangfsdui") #在(ad)分组中加入: '?:'表示去掉匹配默认的优先级,将字符串完全匹配出来,否则只匹配分组即括号中的内容
    172 
    173 管道符:| 表示匹配它两边的内容
    174 
    175 
    176 
    177 元字符之转义符
    178 
    179 反斜杠后边跟元字符去除特殊功能,比如.
    180 反斜杠后边跟普通字符实现特殊功能,比如d
    181 
    182 d  匹配任何十进制数;它相当于类 [0-9]。
    183 D 匹配任何非数字字符;它相当于类 [^0-9]。
    184 s  匹配任何空白字符;它相当于类 [ 	
    
    fv]。
    185 S 匹配任何非空白字符;它相当于类 [^ 	
    
    fv]。
    186 w 匹配任何字母数字字符;它相当于类 [a-zA-Z0-9_]。
    187 W 匹配任何非字母数字字符;它相当于类 [^a-zA-Z0-9_]
    188   匹配一个特殊字符边界,比如空格 ,&,#等
    189 使用的时候需要注意,因为它在ASCII码表中有特殊的意义,表示退格,在python中使用正则表达式,会将代码先交给Python解释器进行解释,而解释器也支持‘’转义符号,然后再交给正则表达式进行匹配,故使用时应该用如下形式:
    190 
    191 ret=re.findall('c\\l','abcle')
    192 print(ret)
    193 执行结果为:['c\l']
    194 
    195 
    196 re模块下的常用方法
    197 import re
    198 #1
    199 re.findall('a','alvin yuan')    #返回所有满足匹配条件的结果,放在列表里
    200 #2
    201 re.search('a','alvin yuan').group()  #函数会在字符串内查找模式匹配,只到找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以
    202  # 通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None。
    203 #3
    204 re.match('a','abc').group()     #同search,不过尽在字符串开始处进行匹配
    205 #4
    206 ret=re.split('[ab]','abcd')     #先按'a'分割得到''和'bcd',在对''和'bcd'分别按'b'分割,可跟分割次数参数
    207 print(ret)#['', '', 'cd']
    208 #5
    209 ret=re.sub('d','abc','alvin5yuan6',1)
    210 print(ret)#alvinabcyuan6
    211 ret=re.subn('d','abc','alvin5yuan6')
    212 print(ret)#('alvinabcyuanabc', 2)
    213 #6
    214 obj=re.compile('d{3}')
    215 ret=obj.search('abc123eeee')
    216 print(ret.group())#123
    217 
    218 
    219 
    220 import re
    221 ret=re.finditer('d','ds3sy4784a')
    222 print(ret)  #<callable_iterator object at 0x10195f940>
    223 print(next(ret).group())
    224 print(next(ret).group())
    225 
    226 
    227 import re
    228 ret=re.findall('www.(baidu|oldboy).com','www.oldboy.com')
    229 print(ret)#['oldboy']  这是因为findall会优先把匹配结果组里内容返回,如果想要匹配结果,取消权限即可
    230 ret=re.findall('www.(?:baidu|oldboy).com','www.oldboy.com')
    231 print(ret)#['www.oldboy.com']
    232 命名分组
    View Code
      1 ***
      2 #logging模块
      3     import logging  
      4     logging.debug('debug message')  
      5     logging.info('info message')  
      6     logging.warning('warning message')  
      7     logging.error('error message')  
      8     logging.critical('critical message')
      9     
     10     运行结果:
     11     C:Python36python.exe C:/Users/Administrator/PycharmProjects/py_fullstack_s4/day34/test.py
     12     WARNING:root:warning message
     13     ERROR:root:error message
     14     CRITICAL:root:critical message
     15 
     16 ***可以看出有一个默认的等级:debug--info--warning(默认)--error--critical***
     17 
     18 ##**配置的两种方式:**
     19 ###1、congfig函数   
     20 
     21     import logging  
     22     logging.basicConfig(level=logging.DEBUG,  
     23                         format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',  
     24                         datefmt='%a, %d %b %Y %H:%M:%S',  
     25                         filename='/tmp/test.log',  
     26                         filemode='w')
     27       
     28     logging.debug('debug message')  
     29     logging.info('info message')  
     30     logging.warning('warning message')  
     31     logging.error('error message')  
     32     logging.critical('critical message')
     33 
     34 ***level表示日志等级,选择DEBUG的话会将所有的都打印出来,最重要的就是format的内容,具体的配置参数如下:***
     35 
     36     可见在logging.basicConfig()函数中可通过具体参数来更改logging模块默认行为,可用参数有
     37     filename:用指定的文件名创建FiledHandler(后边会具体讲解handler的概念),这样日志会被存储在指定的文件中。
     38     filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。
     39     format:指定handler使用的日志显示格式。 
     40     datefmt:指定日期时间格式。 
     41     level:设置rootlogger(后边会讲解具体概念)的日志级别 
     42     stream:用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件(f=open('test.log','w')),默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。
     43     
     44     format参数中可能用到的格式化串:
     45     %(name)s Logger的名字
     46     %(levelno)s 数字形式的日志级别
     47     %(levelname)s 文本形式的日志级别
     48     %(pathname)s 调用日志输出函数的模块的完整路径名,可能没有
     49     %(filename)s 调用日志输出函数的模块的文件名
     50     %(module)s 调用日志输出函数的模块名
     51     %(funcName)s 调用日志输出函数的函数名
     52     %(lineno)d 调用日志输出函数的语句所在的代码行
     53     %(created)f 当前时间,用UNIX标准的表示时间的浮 点数表示
     54     %(relativeCreated)d 输出日志信息时的,自Logger创建以 来的毫秒数
     55     %(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
     56     %(thread)d 线程ID。可能没有
     57     %(threadName)s 线程名。可能没有
     58     %(process)d 进程ID。可能没有
     59     %(message)s用户输出的消息
     60 
     61 
     62 ###2、logger对象
     63 >上述几个例子中我们了解到了logging.debug()、logging.info()、logging.warning()、logging.error()、logging.critical()(分别用以记录不同级别的日志信息),logging.basicConfig()(用默认日志格式(Formatter)为日志系统建立一个默认的流处理器(StreamHandler),设置基础配置(如日志级别等)并加到root logger(根Logger)中)这几个logging模块级别的函数,另外还有一个模块级别的函数是logging.getLogger([name])(返回一个logger对象,如果没有指定名字将返回root logger)
     64 先看一个最简单的过程:
     65 
     66     import logging
     67     
     68     logger = logging.getLogger()
     69     # 创建一个handler,用于写入日志文件
     70     fh = logging.FileHandler('test.log')
     71     
     72     # 再创建一个handler,用于输出到控制台
     73     ch = logging.StreamHandler()
     74     
     75     formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
     76     
     77     fh.setFormatter(formatter)
     78     ch.setFormatter(formatter)
     79     
     80     logger.addHandler(fh) #logger对象可以添加多个fh和ch对象
     81     logger.addHandler(ch)
     82     
     83     logger.debug('logger debug message')
     84     logger.info('logger info message')
     85     logger.warning('logger warning message')
     86     logger.error('logger error message')
     87     logger.critical('logger critical message')
     88     
     89     运行结果:
     90     2017-04-27 09:19:56,145 - root - WARNING - logger warning message
     91     2017-04-27 09:19:56,146 - root - ERROR - logger error message
     92     2017-04-27 09:19:56,146 - root - CRITICAL - logger critical message
     93 
     94 >先简单介绍一下,logging库提供了多个组件:Logger、Handler、Filter、Formatter。Logger对象提供应用程序可直接使用的接口,Handler发送日志到适当的目的地,Filter提供了过滤日志信息的方法,Formatter指定日志显示格式。
     95 >
     96   Logger是一个树形层级结构,输出信息之前都要获得一个Logger(如果没有显示的获取则自动创建并使用root Logger,如第一个例子所示)。
     97 
     98 > logger = logging.getLogger()返回一个默认的Logger也即root Logger,并应用默认的日志级别、Handler和Formatter设置。
     99 当然也可以通过Logger.setLevel(lel)指定最低的日志级别,可用的日志级别有logging.DEBUG、logging.INFO、logging.WARNING、logging.ERROR、logging.CRITICAL。
    100 
    101 >Logger.debug()、Logger.info()、Logger.warning()、Logger.error()、Logger.critical()输出不同级别的日志,只有日志等级大于或等于设置的日志级别的日志才会被输出。
    102 
    103     logger.debug('logger debug message')  
    104     logger.info('logger info message')  
    105     logger.warning('logger warning message')  
    106     logger.error('logger error message')  
    107     logger.critical('logger critical message') 
    108 
    109 >只输出了
    110 
    111     2014-05-06 12:54:43,222 - root - WARNING - logger warning message
    112     2014-05-06 12:54:43,223 - root - ERROR - logger error message
    113     2014-05-06 12:54:43,224 - root - CRITICAL - logger critical message
    114 >从这个输出可以看出logger = logging.getLogger()返回的Logger名为root。这里没有用logger.setLevel(logging.Debug)显示的为logger设置日志级别,所以使用默认的日志级别WARNIING,故结果只输出了大于等于WARNIING级别的信息。
    115 
    116 ***
    117 #序列化模块(json、pickle)
    118 ###什么是序列化?
    119 >我们把对象(变量)从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling,在其他语言中也被称之为serialization,marshalling,flattening等等,都是一个意思。
    120 
    121 >序列化之后,就可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器上。
    122 
    123 >反过来,把变量内容从序列化的对象重新读到内存里称之为反序列化,即unpickling。
    124 
    125 ##json模块
    126 >如果我们要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式,比如XML,但更好的方法是序列化为JSON,因为JSON表示出来就是一个字符串,可以被所有语言读取,也可以方便地存储到磁盘或者通过网络传输。JSON不仅是标准格式,并且比XML更快,而且可以直接在Web页面中读取,非常方便。
    127 
    128 >JSON表示的对象就是标准的JavaScript语言的对象,JSON和Python内置的数据类型对应如下:
    129 
    130 ![](http://i.imgur.com/qbLGmCl.png)
    131 
    132 
    133     #----------------------------序列化
    134     
    135     import json
    136     
    137     dic={'name':'alvin','age':23,'sex':'male'}
    138     print(type(dic))#<class 'dict'>
    139     j=json.dumps(dic)
    140     print(type(j))#<class 'str'>
    141     f=open('序列化对象','w')
    142     f.write(j)  #-------------------等价于json.dump(dic,f)
    143     f.close()
    144     #-----------------------------反序列化<br>
    145     import json
    146     f=open('序列化对象')
    147     data=json.loads(f.read())#  等价于data=json.load(f)
    148 
    149 >d = {'name':'alvin','age':23,'sex':'male'}
    150 >
    151 >f = open("filename",'w')
    152 >
    153 >json.dump(d,f)   #与dumps的区别在于将两步合成一步
    154 >
    155 >f.close()
    156 
    157 
    158 ##pickle模块
    159     ##----------------------------序列化
    160     import pickle
    161     
    162     dic={'name':'alvin','age':23,'sex':'male'}
    163     print(type(dic))#<class 'dict'>
    164     j=pickle.dumps(dic)
    165     print(type(j))#<class 'bytes'>
    166     f=open('序列化对象_pickle','wb')#注意是w是写入str,wb是写入bytes,j是'bytes'
    167     f.write(j)  #-------------------等价于pickle.dump(dic,f
    168     f.close()
    169     #-------------------------反序列化
    170     import pickle
    171     f=open('序列化对象_pickle','rb')
    172     data=pickle.loads(f.read())#  等价于data=pickle.load(f)
    173     print(data['age'])  
    174 >Pickle的问题和所有其他编程语言特有的序列化问题一样,就是它只能用于Python,并且可能不同版本的Python彼此都不兼容,因此,只能用Pickle保存那些不重要的数据,不能成功地反序列化也没关系。
    175 
    176 ***
    177 #re模块
    178 
    179 >就其本质而言,正则表达式(或 RE)是一种小型的、高度专业化的编程语言,(在Python中)它内嵌在Python中,并通过 re 模块实现。正则表达式模式被编译成一系列的字节码,然后由用 C 编写的匹配引擎执行。
    180 
    181 >字符匹配(普通字符,元字符):
    182 
    183 >>1 普通字符:大多数字符和字母都会和自身匹配
    184               >>> re.findall('alvin','yuanaleSxalexwupeiqi')
    185                       ['alvin'] 
    186 
    187 >>2 元字符:. ^ $ * + ? { } [ ] | ( ) 
    188 
    189 
    190 **re.findall("(?:ad)+yuan","adadyuangfsdui") #在(ad)分组中加入: '?:'表示去掉匹配默认的优先级,将字符串完全匹配出来,否则只匹配分组即括号中的内容**
    191 
    192 **管道符:| 表示匹配它两边的内容**
    193 
    194 ![](http://i.imgur.com/lnTzTy9.png)
    195 
    196     元字符之转义符
    197     
    198     反斜杠后边跟元字符去除特殊功能,比如.
    199     反斜杠后边跟普通字符实现特殊功能,比如d
    200     
    201     d  匹配任何十进制数;它相当于类 [0-9]。
    202     D 匹配任何非数字字符;它相当于类 [^0-9]。
    203     s  匹配任何空白字符;它相当于类 [ 	
    
    fv]。
    204     S 匹配任何非空白字符;它相当于类 [^ 	
    
    fv]。
    205     w 匹配任何字母数字字符;它相当于类 [a-zA-Z0-9_]。
    206     W 匹配任何非字母数字字符;它相当于类 [^a-zA-Z0-9_]
    207       匹配一个特殊字符边界,比如空格 ,&,#等
    208 
    209 **使用的时候需要注意,因为它在ASCII码表中有特殊的意义,表示退格,在python中使用正则表达式,会将代码先交给Python解释器进行解释,而解释器也支持‘’转义符号,然后再交给正则表达式进行匹配,故使用时应该用如下形式:**
    210 
    211     ret=re.findall('c\\l','abcle')
    212     print(ret)
    213     执行结果为:['c\l']
    214 
    215 ![](http://i.imgur.com/Rvkvgi3.png)
    216 
    217 ###re模块下的常用方法
    218 
    219     
    220     import re
    221     #1
    222     re.findall('a','alvin yuan')    #返回所有满足匹配条件的结果,放在列表里
    223     #2
    224     re.search('a','alvin yuan').group()  #函数会在字符串内查找模式匹配,只到找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以
    225      # 通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None。
    226     #3
    227     re.match('a','abc').group()     #同search,不过尽在字符串开始处进行匹配
    228     #4
    229     ret=re.split('[ab]','abcd')     #先按'a'分割得到''和'bcd',在对''和'bcd'分别按'b'分割,可跟分割次数参数
    230     print(ret)#['', '', 'cd']
    231     #5
    232     ret=re.sub('d','abc','alvin5yuan6',1)
    233     print(ret)#alvinabcyuan6
    234     ret=re.subn('d','abc','alvin5yuan6')
    235     print(ret)#('alvinabcyuanabc', 2)
    236     #6
    237     obj=re.compile('d{3}')
    238     ret=obj.search('abc123eeee')
    239     print(ret.group())#123
    240 
    241     
    242     
    243     import re
    244     ret=re.finditer('d','ds3sy4784a')
    245     print(ret)  #<callable_iterator object at 0x10195f940>
    246     print(next(ret).group())
    247     print(next(ret).group())
    248 
    249         
    250     import re
    251     ret=re.findall('www.(baidu|oldboy).com','www.oldboy.com')
    252     print(ret)#['oldboy']  这是因为findall会优先把匹配结果组里内容返回,如果想要匹配结果,取消权限即可
    253     ret=re.findall('www.(?:baidu|oldboy).com','www.oldboy.com')
    254     print(ret)#['www.oldboy.com']
    255 
    256 ###命名分组
    257 
    258 ![](http://i.imgur.com/Q6d7y97.png)
    View Code 

    模块链接:常用模块

  • 相关阅读:
    HDU 2157 How many ways?【矩阵快速幂】
    CodeForces 3 D.Least Cost Bracket Sequence【贪心+优先队列】
    【差分】Tallest Cow
    P2220 [HAOI2012]容易题【快速幂】
    无题II HDU
    PHP编译常见错误
    MySQL编译安装
    Tomcat 单(多)实例部署使用
    lvs+keepalived 高可用及负载均衡
    MySQL操作命令梳理(2)
  • 原文地址:https://www.cnblogs.com/george92/p/9260343.html
Copyright © 2011-2022 走看看