zoukankan      html  css  js  c++  java
  • 模块导入,正则表达式,常见模块,异常处理

    一  模块导入

    1. 模块基础

    模块即文件

    模块的分类:

    • 内置模块;
    • 第三方/扩展模块;
    • 自定义模块,模块名一定符合变量名的规范

    导入多个模块:一行导入一个(规范)

    导入顺序:内置模块;第三方;自定义(规范)

    导入模块发生了:

    • 开辟以模块命名的内存空间
    • 执行模块内代码,生成变量字典

    重复导入无效果:第一次导入后就将模块名加载到内存,重复导入仅是对已经加载到内存中的模块对象增加了一次引用,不会重新执行模块内的语句。sys.modules是一个字典,内部包含模块名与模块对象的映射,该字典决定了导入模块时是否需要重新导入。

    不要循环导入

    2 . 导入方式:

    导入方式大致分为导入func和moudle两类,两者差距不大:都在全局命名空间增加相应的名称;两者都会执行moudle中的执行语句

    • import moudle_name (as xxx)
    • from package import moudle_name (as xxx)
    • from moudle_name import func (as xxx)  
    • from package.moudle_name import func (as xxx) 

    from moudle_name import func (as xxx)  的本质是在当前文件的全局变量中加入func名,然后指向moudle_name中的func

    #myfile.py            #注意文件名符合变量规范
    print('the beginning')
    a = 100
    def func():
        print(a)
    
    #myfile2.py
    from myfile import func   # 该func只是函数名,内存地址还是指向上式中的func
    a = 200
    func()        

    the beginning;100      #还是会执行导入模块中的语句

    3.__name__ 

    3.1 __name__介绍

    内置变量,返回当前模块(不是类和函数)的命名空间

    文件执行的两种方式:

    • 以模块形式导入
    • 在pycharm或cmd中以脚本方式直接运行

    应用:用来控制.py文件在不同的应用场景下执行不同的逻辑
      if __name__ == '__main__':

    全局变量__name_:

    • 当文件被当做脚本执行时:__name__ 等于'__main__'
    • 当文件被当做模块导入时:__name__等于模块名

    3.2 sys.moudles[__name__]和sys.moudles[‘__main__’]区别

    反射自身模块(导入模块或者主程序)内容的写法:

    getattr(sys.moudles[__name__],func_name),而不是getattr(sys.moudles[‘__main__’],func_name)

    __name__是个内置变量,'__main__'是个字符串

    #mylife.py
    print
    ('the beginning') import sys print(__name__) print(sys.modules['__main__'])
    print(sys.moudles[__name__]) #因为__name__是个变量,在sys.moudles应该查询字符串‘__mylife__’

    #mylife2.py
    import mylife import sys print(__name__) print(sys.modules['__main__']) #获取当模块 print(sys.moudles[__name__])
    the beginning #导入的文件自动执行 mylife #作为模块导入时,显示模块名
    <module '__main__' from 'E:/2019allstark/practice1/1/a002.py'> #模块中的sys.moudles其实主程序的信息 <module 'mylife' from 'E:\2019allstark\practice1\1\mylife.py'>
    __main__ <module '__main__' from 'E:/2019allstark/practice1/1/a002.py'>
    <module '__main__' from 'E:/2019allstark/practice1/1/a002.py'>

    4.  查找路径

    根据模块名寻找顺序:内存中已经加载的模块->内置模块->sys.path路径中包含的模块(第三方模块在此处);内存、内置、path

    自定义模块切勿与内置模块重名

    ['E:\2019allstark\practice1\mylife',            #当前目录路径,windows中使用\表示路径分隔符防止转义
    'E:\2019allstark\practice1', #当前项目路径
    'D:\PyCharm 2019.1.1\helpers\pycharm_display',
    'C:\Users\matt\AppData\Local\Programs\Python\Python37\python37.zip',
    'C:\Users\matt\AppData\Local\Programs\Python\Python37\DLLs',
    'C:\Users\matt\AppData\Local\Programs\Python\Python37\lib', #部分内置模块,还有一些内置模块由C编写,看不到源码
    'C:\Users\matt\AppData\Local\Programs\Python\Python37',
    'C:\Users\matt\AppData\Local\Programs\Python\Python37\lib\site-packages', #第三方模块
    'C:\Users\matt\AppData\Local\Programs\Python\Python37\lib\site-packages\win32',
    'C:\Users\matt\AppData\Local\Programs\Python\Python37\lib\site-packages\win32\lib',
    'C:\Users\matt\AppData\Local\Programs\Python\Python37\lib\site-packages\Pythonwin',
    'D:\PyCharm 2019.1.1\helpers\pycharm_matplotlib_backend']

     如果导入模块不在sys.path里面,可以用sys.path.append('你要导入的绝对路径')加入。

    import sys, os
    print(os.path.dirname( os.path.abspath(__file__)))  #获取当前文件目录或文件的绝对路径
    sys.path.append(os.path.dirname( os.path.abspath(__file__)))

    5. 包

    包就是含有__init__文件的目录,导入包的本质就是执行包下的__init__文件。切记,包的查找路径包含当前目录和项目目录,项目目录一般定义为:base_path

    注意事项:

    • 凡是在导入时带点的,点的左边都必须是一个包,否则非法;
    • 包A和包B下有同名模块也不会冲突,如A.a与B.a来自两个命名空间(不推荐)

    绝对导入:

    • 从项目目录或根目录开始导入;
    • 绝对路径增删后修改繁琐

    相对导入:

    • 从当前目录导入(sys.path含有当前目录);使用 . 或者 .. 导入。符号 . 代表当前目录,..代表上一级目录,...代表上一级的上一级目录
    • 本文件不能以脚本执行,只能以模块导入的方式执行

    自定义导入:

    执行文件使用绝对导入较繁琐,使用内置变量__file__构造项目目录__file__返回当前文件路径

    import os,sys
    print(__file__)
    ret = __file__.split('/')
    ret = ret[:-2]
    base_path= '/'.join(ret)          
    # base_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))   #(推荐此方法);os.path.dirname(),返回目录名;os.path.abspath()返回绝对路径;
    sys.path.append(base_path)

    E:/2019allstark/practice1/path1/a1.py #file在pycharm返回绝对路径,在cmd返回相对路径

    参考:__file__返回路径解析

    https://www.cnblogs.com/jyfootprint/p/9429346.html

    二  正则表达式

    正则表达式(regular expression)描述了一种字符串匹配的模式(pattern)。

    将正则表达式放到带匹配字符串从头到尾一一匹配。

    1. 正则基础

    1.1 字符组

    在一个字符的位置上允许出现字符的组合,字符组表示的是一个字符的位置

    字符组 举例 说明
    枚举 [0123456] 内部是or的关系
    范围 [1-9] -  表示范围匹配
    组合 [1-9abcA-Z] 只能检测  -  左右两边各一个字符,进而确定范围

    1.2 元字符

    简化字符组的写法

    元字符 匹配内容 元字符 匹配内容
    . 除换行符( )以外的任意字符 ^,A 开始
    d 数字 $, 结尾
    w 数字、字符、下划线 a|b a或b(优先匹配a;a、b相似,a长)
    s 空格、 、 ()  
    D 非数字 [...] 字符组
    W 非(数字、字符、下划线) [^...]
    S 非(空格、 、 )    
    换行符    
    制表符    
     边界(开始、结尾、空格)    

    1.3 量词

    量词只作用于前边一个元字符

    量词 含义
    * 重复0次或多次
    + 重复1次或多次
    出现0次或1次(可有可无)
    {n} 重复n次
    {n,} 重复至少n次
    {n,m} 重复n到m次

    贪婪匹配:匹配尽可能多的内容,程序默认,采用回溯算法;

    惰性匹配:匹配尽可能少的内容,调用方法为在量词后边加一个问号?

    转义符:只会对\起作用

    mm = "c:\ab\bc\cd\"
    print(mm)
    mm = r"c:\ab\bc\cd\"
    print(mm)
    mm = "c:\ab\bc\cd\"
    print(mm)
    mm = r"c:\ab\bc\cd\"
    print(mm)
    # mm = r"c:\ab\bc\cd"
    # print(mm)
    # mm = "c:\ab\bc\cd"
    # print(mm)

    2. 常用方法

    2.1 re.finall(pattern, string)

      以列表的形式返回匹配到的值

    2.2 re.search(pattern, string);

      以对象的形式返回匹配到值,只会匹配字符串第一个值,配合result.group()查看,匹配不到返回None

    2.3 re.match(pattern, string)

      完全等效于re.search(^str)

    2.4 re.sub(pattern, repl, string, count=0)

      相当于字符串的replace方法,返回值为修改后的字符串

    2.5 re.sub(pattern, repl, string, count=0)

      返回值是元组:(str,n),n表示替换的次数

    2.6 re.split(pattern, string)

      相当于字符串的split,返回值为列表

    2.7 re.comfile(pattern)

      将正则模式存储在result中,允许多次调用,节省时间

    2.8 re.finditer()

      将匹配结果存储在可迭代对象中,一般使用for循环调用

    import re
    print(re.findall('d+', '123matt456logan'))
    print(re.search('d+','123matt456logan').group())
    print(re.match('d+','123matt456logan'))
    print(re.sub('d+','AAA','123matt456logan'))
    print(re.subn('d+','AAA','123matt456logan'))
    print(re.split('d+','123matt456logan'))
    ret = re.compile('d+')
    print(ret)
    print(ret.findall('123matt456logan'))
    print(re.finditer('d+', '123matt456logan'))
    
    ['123', '456']
    123
    <re.Match object; span=(0, 3), match='123'>
    AAAmattAAAlogan
    ('AAAmattAAAlogan', 2)
    ['', 'matt', 'logan']              #分割时会产生空字符
    re.compile('\d+')                 
    ['123', '456']
    <callable_iterator object at 0x00000000027C89E8>

    3. 分组

    使用分组会产生诸多特性

    3.1 re.findall()分组特性

    分组部分优先显示,经常配合‘’或  |‘’用于优先显示

    import re
    print(re.findall('d+w', '123matt456Logan'))
    print(re.findall('d+(w)', '123matt456Logan'))
    print(re.findall('d+(?:.d+)|d+', '12-252+26-3*89/25-25.36*56+5.25'))
    print(re.findall('d+(?:.d+)|(d+)', '12-252+26-3*89/25-25.36*56+5.25'))
    
    ['123m', '456L']
    ['m', 'L']
    ['12', '252', '26', '3', '89', '25', '25.36', '56', '5.25']
    ['12', '252', '26', '3', '89', '25', '', '56', '']              #没显示部分为空白

    3.2 re.search() 分组特性

    实现括号的定位显示

    print(re.search('d+w+', '123matt-456Logan'))
    ret = re.search('d+(w)(w)(w)', '123matt-456Logan')
    print(ret.group(0));print(ret.group(1));print(ret.group(2));print(ret.group(3))  #定位括号

    123mat; m; a; t       #result.group(int = 0)

    3.3 re.split()分组特性

    显示分割内容

    print(re.split('d+', '123matt-456Logan'))
    print(re.split('(d+)', '123matt-456Logan'))
    
    ['', 'matt-', 'Logan']
    ['', '123', 'matt-', '456', 'Logan']

    3 4 分组命名

    print(re.search('<w+>w+</w+>', '<h1>abcdef</h1>').group())
    ret = re.search('<(?P<id1>w+)>w+</(?P=id1)>', '<h1>abcdef</h1>')   #分组关键字形式
    print(ret.group())                              #全部显示
    print(ret.group(1))
    # print(ret.group(2))                           #报错,分组命名前后()表示一个
    print(ret.group('id1'))                         #显示对应名称的分组()内容
    res = re.search(r'<(?P<id1>w+)>w+<(/1)>', '<h1>abcdef</h1>')      #分组位置形式
    
    <h1>abcdef</h1>
    <h1>abcdef</h1>
    h1; h1

    三  time模块

    1. 时间形式

    • timestamp:时间戳,从1970年1月1日00:00:00开始按秒计算,北京时间为从8时开始计算;
    • struct_time:时间元组,共有九个元素组;
    • format time :格式化时间,已格式化的结构使时间更具可读性。包括自定义格式和固定格式。

    1.1 时间戳

    生成函数:time.time()

    print(time.time())    #1567067674.6788714,从1970年1月1日08:00:00计算的秒数

    1.2 时间元组

    伪生成函数:time.localtime(seconds=None);When 'seconds' is not passed in, convert the current time instead.

    print(time.localtime())    #返回值为struct_time对象格式
    print(time.localtime().tm_year)
    
    time.struct_time(tm_year=2019, tm_mon=8, tm_mday=29, tm_hour=18, tm_min=29, tm_sec=14, tm_wday=3, tm_yday=241, tm_isdst=0)
    2019
                属性                            值
        tm_year(年)                  比如2017 
        tm_mon(月)                   1 - 12
        tm_mday(日)                  1 - 31
        tm_hour(时)                  0 - 23
        tm_min(分)                   0 - 59
        tm_sec(秒)                   0 - 61
        tm_wday(weekday)             0 - 6(0表示周日)
        tm_yday(一年中的第几天)        1 - 366
        tm_isdst(是否是夏令时)        默认为-1    

    1.3 格式化字符串时间

    伪生成函数:time.strftime(format,p_tuple=None);When the time tupleis not present, current time as returned by localtime() is used.

    print(time.strftime('%Y-%m-%d %X'))
    2019-08-29 18:09:27
    %y 两位数的年份表示(00-99%Y 四位数的年份表示(000-9999%m 月份(01-12%d 月内中的一天(0-31%H 24小时制小时数(0-23%I 12小时制小时数(01-12%M 分钟数(00=59%S 秒(00-59%a 本地简化星期名称
    %A 本地完整星期名称
    %b 本地简化的月份名称
    %B 本地完整的月份名称
    %c 本地相应的日期表示和时间表示
    %j 年内的一天(001-366%p 本地A.M.或P.M.的等价符
    %U 一年中的星期数(00-53)星期天为星期的开始
    %w 星期(0-6),星期天为星期的开始
    %W 一年中的星期数(00-53)星期一为星期的开始
    %x 本地相应的日期表示
    %X 本地相应的时间表示
    %Z 当前时区的名称
    %% %号本身

    2. 三种格式转化

    1、time.localtim(seconds=None)

      返回时间戳的struct_time格式;

    2、time.mktime(p_tuple)

      将struct_time格式转成时间戳;

    3、time.strftime("%Y-%m-%d %H:%M:%S",p_tuple=None )

      将struct_time格式转成指定的字符串格式

    4、time.strptime("2016/05/22","%Y/%m/%d")

      将日期字符串转成 struct_time格式

    import time
    print(time.time())
    print(time.localtime(1500000000))
    print(time.strftime('%Y-%m-%d'))
    print(time.strptime('2019-08-30','%Y-%m-%d'))     #'%Y-%m-%d'为'2019-08-30'的识别模式
    
    1567076841.7220666
    time.struct_time(tm_year=2017, tm_mon=7, tm_mday=14, tm_hour=10, tm_min=40, tm_sec=0, tm_wday=4, tm_yday=195, tm_isdst=0)
    2019-08-29
    time.struct_time(tm_year=2019, tm_mon=8, tm_mday=30, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=4, tm_yday=242, tm_isdst=-1)

     时间差练习:只有时间戳能加减

    import time
    true_time=time.mktime(time.strptime('2018-09-11 08:30:00','%Y-%m-%d %H:%M:%S'))
    time_now=time.time()    
    dif_time=time_now-true_time                       
    struct_time=time.gmtime(dif_time)
    print('过去了%d年%d月%d天%d小时%d分钟%d秒'%(struct_time.tm_year-1970,struct_time.tm_mon-1,
                                           struct_time.tm_mday-1,struct_time.tm_hour,
                                           struct_time.tm_min,struct_time.tm_sec))

    过去了0年11月18天10小时42分钟25秒

    3. 固定格式转化

     

    5、time.ctime(second=None)

      转化为C格式字符串 

    6、time.asctime(p_tuple=None)

      与time.strftime类似,转化为C格式字符串

    import time
    print(time.ctime())
    print(time.asctime())
    
    Thu Aug 29 19:21:33 2019   #西方习惯的格式
    Thu Aug 29 19:21:33 2019

    四  datetime模块

    datetime模块封装了time模块,提供更多接口,内部的类有:date,time,datetime,timedelta,tzinfo。

    1. date类

    def __init__(self, year: int, month: int, day: int),提供日期的操作

    1、obj = date(2017,8,8)

      初始化函数,创建date类型的对象

    2、date.today()

      返回当前本地日期

    3、date.fromtimestamp(timestamp)

      返回时间戳的日期

    4、date.strftime(format)

      返回自定义格式的时间字符串

    5、replace(year, month, day):

      生成一个新的date对象,指定参数替换

    2. time类

    def __init__(self, hour, minute, second, microsecond, tzinfo)

    6、datetime.time()

      初始化函数

    7、time_obj. hour/min/sec/micsec()

      返回小时/分钟/秒/毫秒

    8、time_obj. isoformat()

      返回型如"HH:MM:SS"格式的字符串表示

    3. datetime类

    封装time模块

    4. timedelta类

    9、timedelta(days,hours,minutes,second,microseconds,weeks)

      初始化函数

    10、timedelta_obj. days/secons/microseconds()

      返回天数、秒、毫秒,没有小时,分钟

    加减操作

    • datetime_obj = datetime_obj  +/-   timedelta_obj
    • timedelta_obj = datetime_obj - datetime_obj 

    date与datetime对象都可进行加减操作

    import datetime
    t1 = datetime.datetime.now()
    delta = datetime.timedelta(weeks=1)        #默认为days=1
    print(t1 + delta)
    t3 = datetime.datetime(2019, 12, 26, 10, 10, 10)
    print(t3 - t1);print((t3 - t1).days)
    
    2019-09-06 12:44:34.275388
    117 days, 21:25:35.724612; 117

    参考:datetime模块详解

    https://www.cnblogs.com/xtsec/p/6682052.html

    五  random模块

    1. 整数

    1、random.randint(1,6)  随机生成指定范围 [a,b] 的整数

    2、rangdom.randrange(1,100,2)  随机生成指定范围 [a,b] 的整数,步长为2

    2. 浮点数

    3、random.random()  随机生成指定范围 [0,1) 的浮点数

    4、random.uniform(a,b)  随机生成指定范围 [a,1) 的浮点数

    源码  a + (b-a) * self.random()

    3. 抽取

    5、random.choice(seq)  随机抽取元素

    Some built-in sequence types are list, str, tuple and bytes 

    6、random.sample(Population,k)  随机抽取k个元素

    Population must be a sequence or set. For dicts, use list(d)

    4. 打乱

    7、random.shuffle(list)  随机打乱顺序

    return None

    #随机验证码实例
    import
    random check_code = '' for i in range(4): cur = random.randrange(0,4) #随机猜的范围,与循环次数相等 #字母 if cur == i: tmp = chr(random.randint(65,90)) #数字 else: tmp = random.randint(0,9)    #randint包含最后一位 check_code += str(tmp) print(check_code)

    六  os模块

    1 基本方法

    os模块是与操作系统交互的一个接口

    # 当前执行这个python文件的工作目录相关的工作路径
    os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径;与(__file__)返回的文件路径不相同
    os.chdir("dirname") 改变当前脚本工作目录;相当于shell下cd 

    # 和目录相关
    os.makedirs(name,exit_ok=False) 可生成多层递归目录,最底层目录存在时报错;
    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.popen("bash command).read() 运行shell命令,获取执行结果;返回对象,以read()打开 
    os.environ 获取系统环境变量 

    # path系列,和路径相关
    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) 返回文件的大小 

    os.urandom(int) 返回int位的bytes

    os.getpid()  返回进程的号

    os.getppid()  返回父进程号

     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)是创建时间(详细信息参见平台的文档)。

    2. 获取文件夹大小

      os.walk() 方法用于通过在目录树中游走输出在目录中的文件名,向下递归。

    os.walk(top[, topdown=True[, onerror=None[, followlinks=False]]])
    • top -- 是你所要遍历的目录的地址, 返回值是一个三元组(root,dirs,files)。

      • root 所指的是当前正在遍历的这个文件夹的本身的地址
      • dirs 是一个 list ,内容是该文件夹中所有的目录的名字(不包括子目录)
      • files 同样是 list , 内容是该文件夹中所有的文件(不包括子目录)
    • topdown --可选,为 True,则优先遍历 top 目录,否则优先遍历 top 的子目录。如果 topdown 参数为 True,walk 会遍历top文件夹,与top 文件夹中每一个子目录。

    • onerror -- 可选,需要一个 callable 对象,当 walk 需要异常时,会调用。

    • followlinks -- 可选,如果为 True,则会遍历目录下的快捷方式(linux 下是软连接 symbolic link )实际所指的目录(默认关闭),如果为 False,则优先遍历 top 的子目录。

    import os
    def getdirsize(dir):
        size = 0
        for root, dirs, files in os.walk(dir):
            size += sum([os.path.getsize(os.path.join(root, name)) for name in files])  #生成列表再相加
        return size
    if __name__ == '__main__':
        size = getdirsize(os.getcwd())
        print('There are %.3f Mb' %(size/1024/1024))   #保留小数的位数

    七  sys模块

    与python解释器交互的命令

    sys.argv           命令行参数List,第一个元素是程序本身路径,例如cmd中输入mysql -uroot -ppwd;sys.argv[0]='mysql'; sys.argv[1]='-uroot'; sys.argv[2]='-ppwd'
    sys.exit(n)        退出程序,正常退出时exit(0),错误退出sys.exit(1)
    sys.version        获取Python解释程序的版本信息
    sys.path           返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
    sys.platform       返回操作系统平台名称

    八  json & picle模块

    json 和 pickal模块都只有四个方法: dumps、dump、loads、load

    1.  json四种方法

    JSON (JavaScript Object Notation)是一种使用广泛的轻量数据格式,主要用于数据交互。json和js对象格式一样,字符串中的属性名必须加双引号其他得和js语法一致。

    json生成的数据存在于内存,需要write和read进行存储和读取。

    JSON和Python之间的数据转换对应关系如下表:(不支持set)

    JSONPython
    object dict
    array list、tuple
    string str
    number (int) int
    number (real) float
    true True
    false False
    null None

    json方法大致分为:

    • 网络传输:dumps、loads
    • 文件读写:dump、load

    1.1  dumps(obj)、dump(obj,fp)

      用于将 Python 对象编码成 JSON 字符串

    1.2  loads(obj)、load(fp)

      用于解码 JSON 数据;返回 Python 字段的数据类型

    import json
    dic = {'a': 1, 'b': 2}
    dic_json = json.dumps(dic)
    print([dic_json])             #print([ ])加上[]为真实打印,附带数据类型
    dic_new = json.loads(dic_json)
    print([dic_new])
    with open('file', 'w')as f:  
        json.dump(dic, f)         
    with open('file')as f2:
        aaa = json.load(f2)
    print([aaa])

    ['{"a": 1, "b": 2}'];[{'a': 1, 'b': 2}];[{'a': 1, 'b': 2}]

    1.3 格式化显示

    import json
    data = {'username': ['李华', '二愣子'], 'sex': 'male', 'age': 16}   #针对字典类型
    json_dic2 = json.dumps(data, sort_keys=True, indent=2, separators=(',', ':'), ensure_ascii=False)   #ensure_asscii = True显示Unicode编码,不显示汉字
    print(json_dic2)
    
    {
      "age":16,
      "sex":"male",
      "username":[
        "李华",
        "二愣子"
      ]
    }

    2. json限制

    2.1 json转化字典时, keys must be str, int, float, bool or None

      key不接受元组,且数字必须字符串化

      元组在做value时,会被转换为list

    2.2 双引号

      json生成和导入字符串时必须是双引号

    2.3 文件允许多次dump,不允许多次load

    import json
    dic1 = {1: 'a', 2: 'b'}
    dic2 = {'c': 3, 'd': 4}
    with open('file', 'w') as f:
        # json.dump(dic1, f)         形成数据黏连,在一行中
        # json.dump(dic2, f)
        ret1 = json.dumps(dic1)
        ret2 = json.dumps(dic2)
        f.write(ret1 + '
    ')
        f.write(ret2 + '
    ')
    with open('file') as f2:
        # json.load(f2)             不允许读取多个数据
        for line in f2:
            ret = json.loads(line)
            print(ret)

    {'1': 'a', '2': 'b'};{'c': 3, 'd': 4}

    3.  pickle特性

    pickle模块是将Python所有的数据结构以及对象等转化成bytes类型,然后还可以反序列化还原回去。pickle都是bytes类型

    json模块序列化出来的是通用格式,其它编程语言都认识,就是普通的字符串;pickle模块序列化出来的只有python可以认识,其他编程语言表现为乱码

    pickle可以序列化函数;反序列化时,读取文件中需要有该函数的定义(定义和参数必须相同,内容可以不同)

    pickle方法:

    • 传输:loads(obj)、dumps(obj)
    • 文件操作:load(fp)、dump(obj,fp)

    3.1 pickle支持几乎所有数据类型

    3.2 pickle支持序列化自定义对象和函数

    3.2 pickle支持多次存储和读取

    import pickle
    def func():      #反序列化时必须在
        print('aaa')
    class Student:
        def __init__(self, name, age):        #反序列化时必须在
            self.name = name
            self.age = age
    s1 = Student('matt', 20)
    with open('file', 'wb') as f:      #每次写入会有标识,二进制形式写入
        pickle.dump(func, f)
        pickle.dump(s1, f)
    with open('file', 'rb') as f2:
        while True:
            try:                           #多次读取的格式,多次写入就多少次读取,不能一次读取
                print(pickle.load(f2))
            except EOFError:
                break
    
    <function func at 0x00000000005EC1E0>
    <__main__.Student object at 0x00000000027D8E48>

    参考:json详细解析

    https://www.jb51.net/article/139498.htm

    九  hashlib模块

    1. 模块介绍

    此模块通过一个函数,把任意长度的数据转换为一个固定长度的数据串,又称为摘要算法,加密算法,哈希算法,散列算法等等,算法有md5, sha1, sha224, sha256, sha384, sha512。

    md5是常用的算法,主要是速度快。

    import hashlib
    md5 = hashlib.md5()     #创建md5对象
    md5.update('how to use md5 in python hashlib?'.encode())
    md5.update(b'haha')     #update的数据必须是bytes   
    print(md5.hexdigest())    
    
    #文件读取
    def file_check(file_path): with open(file_path,mode='rb') as f1: sha256 = hashlib.sha256() while 1: content = f1.read(1024) if content: sha256.update(content) else: return sha256.hexdigest()

    2. hmac

    基本与hashlib用法一致,在加salt时方便一点

    import hmac
    message = b'Hello, world!'
    key = b'secret'
    h = hmac.new(key, message, digestmod='MD5')  # 如果消息很长,可以多次调用h.update(msg)
    print(h.hexdigest())

    十  logging模块

    logging模块是Python内置的标准模块,主要用于输出运行日志,可以设置输出日志的等级、日志保存路径、日志文件回滚等;相比print,具备如下优点:

    • 可以通过设置不同的日志等级,只输出重要信息,而不必显示大量的调试信息;
    • print将所有信息都输出到标准输出中(screen);logging则可以设置信息输出的文件和格式;

    1. 函数式配置

    该方法简单,但定制型差:只能屏幕或文件输出一种、没有encode()选项,文件显示中文乱码

    import logging
    logging.basicConfig(
        format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s', 
        datefmt='%Y-%m-%d %H:%M:%S %p',
        filename='file'      #没有改语句时、屏幕显示,没有encoding选项
        level=logging.ERROR    #输出等级,一般都是INFO等级
    )
    logging.error('你好')

    2019-08-31 11:45:03 AM - root - ERROR -test100: ��� #文件输出中文乱码

    logging.basicConfig()函数中可通过具体参数来更改logging模块默认行为,可用参数有:

    filename:用指定的文件名创建FiledHandler,这样日志会被存储在指定的文件中。
    filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。
    format:指定handler使用的日志显示格式。
    datefmt:指定日期时间格式。
    level:设置rootlogger(后边会讲解具体概念)的日志级别   #level = logging.DEBUG
    stream:用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件(f=open(‘test.log’,’w’)),默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。
    handles:
    没有encoding选项,只能以ANSI(本地字符编码)输出

    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用户输出的消息

    输出等级

    FATAL:致命错误
    CRITICAL:50,特别糟糕的事情,如内存耗尽、磁盘空间为空,一般很少使用
    ERROR:40,发生错误时,如IO操作失败或者连接问题
    WARNING:30,发生很重要的事件,但是并不是错误时,如用户登录密码错误
    INFO:20,处理请求或者状态变化等日常事务
    DEBUG:10,调试过程中使用DEBUG等级,如算法中每个循环的中间状态

    2. 对象配置

    import logging
    logger = logging.getLogger()     #1、创建一个logger对象
    fh = logging.FileHandler('file_name',encoding='utf-8')     #2、创建一个文件管理操作符   #函数配置没有encoding选项
    sh = logging.StreamHandler()   #3、创建一个屏幕管理操作符
    #4、创建一个日志输出的格式
    fm1 = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    fh.setLevel(logging.DEBUG)      #5、设置输出等级
    fh.setFormatter(fm1)        #6、文件管理操作符绑定一个格式
    sh.setFormatter(fm1)        #7、屏幕管理操作符绑定一个格式
    logger.addHandler(fh)       #8、logger对象绑定文件管理操作符
    logger.addHandler(sh)       #9、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')   #屏幕和文件同时输出

    参考:logging模块解析

    https://www.cnblogs.com/liujiacai/p/7804848.html

    十一  异常处理

    1. 异常基础

    常见的异常:

    AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x
    IOError 输入/输出异常;基本上是无法打开文件
    ImportError 无法引入模块或包;基本上是路径问题或名称错误
    IndentationError 语法错误(的子类) ;代码没有正确对齐
    IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]
    KeyError 试图访问字典里不存在的键
    KeyboardInterrupt Ctrl+C被按下
    NameError 使用一个还未被赋予对象的变量
    SyntaxError Python代码非法,代码不能编译(个人认为这是语法错误,写错了)
    TypeError 传入对象类型与要求的不符合
    UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,
    导致你以为正在访问它
    ValueError 传入一个调用者不期望的值,即使值的类型是正确的

    2. 异常处理语句

     发生异常后,会执行exit(),直接退出程序

    异常处理只能处理指定、有限的异常,因为异常类的数量是一定的。

    2.1 try/except

      基础语法,最常用

    try:
        a = [1, 2]
        b = a[5]               #发生异常
    except (ValueError,IndexError) as e:     #多状况,发生任何一种都触发
        print(e)
    print('aaa')           #发生错误,能够执行

    list index out of range;aaa

    发生错误后只是try中的程序不再执行,而执行except中的语句,之后再执行主程序。即使发生错误,下端的主程序也能执行。

    2.2 try/except/else

      类似于for/else语句:for正常走完能执行else语句,若for内部有break,则不执行else语句

    try:
        a = [1, 2]
        b = a[1]
    except IndexError as e:
        print(e)
    else:                  #未发生错误,执行else,发生错误,不执行else
        print('aaa')
    print('bbb')

    aaa;bbb

    2.3 try/except(/excepy)/finally

      不管是否发生错误,都会执行finally语句,比下端主程序更安全

    try:
        a = [1, 2]
        b = a[3]
    except IndexError as e:print(e)
    else:print('aaa')
    finally:print('bbb')

    aaa;bbb

    3. Exception

      万能异常,Exception包含了所有的异常类

    try:
        a = [1, 2]
        b = a[3]
    except Exception as e:   #不用指定异常类的类名,方便一些,但一定打印信息
        print(e)

    4. raise

      主动抛出异常,能改写异常类的具体信息

    try:
        a = [1, 2]
        b = a[3]
        # raise ValueError('aaa')    #这样抛出异常会打印aaa
    except Exception as e:
        print(e)
        raise                   #源码中常见,原封不动抛出异常

    list index out of range
    Traceback (most recent call last):
    File "E:/2019allstark/soft/core/test100.py", line 3, in <module>
    b = a[3]
    IndexError: list index out of range

    5. 自定义异常

    class EvaException(Exception):
        def __init__(self, msg):
            self.msg = msg
        def __str__(self):
            return self.msg
    try:
        raise EvaException('类型错误')
    except EvaException as e:
        print(e)

    6. assert

      源码中个经常出现,assert只有True和False,主要判断源码中继续执行的条件是否准备好。

    assert True    #ture继续往下走
    print('aaa')
    assert 0       #false报错
    print('bbb')

    aaa
    Traceback (most recent call last):
    File "E:/2019allstark/soft/core/test100.py", line 3, in <module>
    assert 0
    AssertionError

  • 相关阅读:
    HTTP && 缓存
    querySelector $() getElementBy区别
    Canvas 雾玻璃
    Github page
    Browserify
    关于布局和结构
    how to install flash
    kali update can’t found win7 loader
    arp spoofing
    How To Set Up Port Forwarding in Linux
  • 原文地址:https://www.cnblogs.com/mushuiyishan/p/10471088.html
Copyright © 2011-2022 走看看