• Python全栈开发之5、模块


    一、模块

    1、import导入模块

    #1.定义
    模块:用来从逻辑上组织python代码(变量,函数,类,逻辑),本质就是.py结尾的python文件,实现一个功能
    包:python package 用来从逻辑上组织模块  本质就是一个目录(必须带有一个__init__.py的文件)
    
    #2.导入方法
    import module
    import module1,module2   导入多个模块
    from module import *     导入所有  不推荐慎用(可能会覆盖本文件中自定义的同名函数)
    from module  import  logger as logger_sunhao   创建别名
    from module import m1,m2,m3
    
    #3.import模块本质(路径搜索和搜索路径)
    import sys
    print(sys.path)  sys.path路径就是当前执行文件所在的路径
    import module ---> module.py ----> module.py的路径 ---> sys.path
    
    #4.导入优化
    from module_test import test
    
    #5.模块的分类
      1.标准库
        time与datetime
      2.开源模块
      3.自定义模块

     

     #1、bin执行文件的路径是'E:\Python学习2019',如果想调用web3目录下的main.py模块,需要  from web1.web2.web3 import main  这样调用

    #2、main.py和cal.py虽然都在web3目录下,但是如果main.py想调用cal.py必须这样写:from web1.web2.web3 import cal  因为执行文件的路径只有一个就是:'E:\Python学习2019'

    #3、bin和module目录是同级目录,如果想在bin.py中直接from module import main调用module目录中的文件,需要把路径加到环境变量中。
    BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    sys.path.append(BASE_DIR)

    二、动态导入模块 importlib.import_module

     

    三、time和datetime时间模块

    1、time

    在Python中,通常有这几种方式来表示时间:
    
    1、时间戳
    2、格式化的时间字符串
    3、元组(struct_time)共九个元素。
    
    由于Python的time模块实现主要调用C库,所以各个平台可能有所不同。
    
    UTC(Coordinated Universal Time,世界协调时)亦即格林威治天文时间,世界标准时间。在中国为UTC+8。DST(Daylight Saving Time)即夏令时。
    
    时间戳(timestamp)的方式:通常来说,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量。我们运行“type(time.time())”,返回的是float类型。返回时间戳方式的函数主要有time(),clock()等。
    
    元组(struct_time)方式:struct_time元组共有9个元素,返回struct_time的函数主要有gmtime(),localtime(),strptime()。下面列出这种方式元组中的几个元素:
     1 # -*-coding:utf-8-*-
     2 import time
     3 print(time.time())      #获取一个时间戳 从1970年开始按秒计时的一个浮点型数值
     4 print(time.localtime()) #返回一个struct_time元组类型序列 里面元素包含年,月,日等九个元素
     5 print(time.timezone)    #返回一个值 单位为秒 
     6 print(time.asctime())   #返回当前时间字符串格式
     7 time.sleep(2) #睡眠几秒
     8 
     9 time.gmtime()  #把时间戳转换成元组,但是时间是UTC时间
    10 time.gmtime(time.time()-time.timezone)  #把UTC时间转换成当地时间
    11 print(time.localtime())  #把时间戳转换成元组,但是时间是当地时间  结果为UTC+8时区
    x=time.localtime()
    print(x.tm_year)  #获取年
    print(x.tm_mon)  #获取月
    print(x.tm_mday) #获取日
    print(x.tm_hour)  #获取时
    print(x.tm_min)  #获取分
    print(time.mktime(x)) #元组转换成时间戳
    
    #元组转换成格式化字符串时间
    time.strftime("%Y-%m-%d  %H:%M:%S",time.localtime())  
    
    #把格式化字符串转换成元组
    time.strptime('2017-10-17','%Y-%m-%d')  
    %a    本地(locale)简化星期名称    
    %A    本地完整星期名称    
    %b    本地简化月份名称    
    %B    本地完整月份名称    
    %c    本地相应的日期和时间表示    
    %d    一个月中的第几天(01 - 31%H    一天中的第几个小时(24小时制,00 - 23%I    第几个小时(12小时制,01 - 12%j    一年中的第几天(001 - 366%m    月份(01 - 12%M    分钟数(00 - 59%p    本地am或者pm的相应符    一    
    %S    秒(01 - 61)    二    
    %U    一年中的星期数。(00 - 53星期天是一个星期的开始。)第一个星期天之前的所有天数都放在第0周。    三    
    %w    一个星期中的第几天(0 - 6,0是星期天)    三    
    %W    和%U基本相同,不同的是%W以星期一为一个星期的开始。    
    %x    本地相应日期    
    %X    本地相应时间    
    %y    去掉世纪的年份(00 - 99%Y    完整的年份    
    %Z    时区的名字(如果不存在为空字符)    
    %%    ‘%’字符

    2、datetime时间模块

    import datetime
     
    # print(datetime.datetime.now()) #返回 2016-08-19 12:47:03.941925
    #print(datetime.date.fromtimestamp(time.time()) )  # 时间戳直接转成日期格式 2016-08-19
    # print(datetime.datetime.now() )
    # print(datetime.datetime.now() + datetime.timedelta(3)) #当前时间+3天
    # print(datetime.datetime.now() + datetime.timedelta(-3)) #当前时间-3天
    # print(datetime.datetime.now() + datetime.timedelta(hours=3)) #当前时间+3小时
    # print(datetime.datetime.now() + datetime.timedelta(minutes=30)) #当前时间+30分
    # c_time  = datetime.datetime.now()
    # print(c_time.replace(minute=3,hour=2)) #时间替换

     四、 re模块(正则表达式)

    '.'     默认匹配除
    之外的任意一个字符,若指定flag DOTALL,则匹配任意字符,包括换行
    '^'     匹配字符开头,若指定flags MULTILINE,这种也可以匹配上(r"^a","
    abc
    eee",flags=re.MULTILINE)
    '$'     匹配字符结尾,或e.search("foo$","bfoo
    sdfsf",flags=re.MULTILINE).group()也可以
    '*'     匹配*号前的字符0次或多次,re.findall("ab*","cabb3abcbbac")  结果为['abb', 'ab', 'a']
    '+'     匹配前一个字符1次或多次,re.findall("ab+","ab+cd+abb+bba") 结果['ab', 'abb']
    '?'     匹配前一个字符1次或0次
    '{m}'   匹配前一个字符m次
    '{n,m}' 匹配前一个字符n到m次,re.findall("ab{1,3}","abb abc abbcbbb") 结果'abb', 'ab', 'abb']
    '|'     匹配|左或|右的字符,re.search("abc|ABC","ABCBabcCD").group() 结果'ABC'
    '(...)' 分组匹配,re.search("(abc){2}a(123|456)c", "abcabca456c").group() 结果 abcabca456c
     
     
    'A'    只从字符开头匹配,re.search("Aabc","alexabc") 是匹配不到的
    ''    匹配字符结尾,同$
    'd'    匹配数字0-9
    'D'    匹配非数字
    'w'    匹配[A-Za-z0-9]
    'W'    匹配非[A-Za-z0-9]
    's'     匹配空白字符、	、
    、
     , re.search("s+","ab	c1
    3").group() 结果 '	'
     
    '(?P<name>...)' 分组匹配 re.search("(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{4})","371481199306143242").groupdict("city") 结果{'province': '3714', 'city': '81', 'birthday': '1993'} 
    常用正则表达式符号
    re.match   # 只从开头开始匹配 
    re.search  # 从整个文本匹配 返回一个对象  这个对象调用group()方法 查看 
    re.findall    # 把所有匹配到的字符放到以列表中的元素返回    #返回所有满足匹配条件的结果,放在列表里
    re.splitall   # 以匹配到的字符当做列表分隔符
    re.sub       # 匹配字符并替换  ret = re.sub('a..a','skmb','hasascascasda') print(ret)
    
    re.splite
    obj = re.compile('.com')    #编译方法  先把要匹配的字符串编译成一个对象  
    ret = obj.findall('asdasd.comasdas')
    print(ret)
    用法

     五、random随机模块

    import random
    print (random.random())  #0.6445010863311293  
    #random.random()用于生成一个0到1的随机符点数: 0 <= n < 1.0

    print (random.randint(1,7)) #4 #random.randint()的函数原型为:random.randint(a, b),用于生成一个指定范围内的整数。 # 其中参数a是下限,参数b是上限,生成的随机数n: a <= n <= b

    print (random.randrange(1,10)) #5 #random.randrange的函数原型为:random.randrange([start], stop[, step]), # 从指定范围内,按指定基数递增的集合中 获取一个随机数。如:random.randrange(10, 100, 2), # 结果相当于从[10, 12, 14, 16, ... 96, 98]序列中获取一个随机数。 # random.randrange(10, 100, 2)在结果上与 random.choice(range(10, 100, 2) 等效。
    print(random.choice('liukuni')) #i

    #random.choice从序列中获取一个随机元素。 # 其函数原型为:random.choice(sequence)。参数sequence表示一个有序类型。 # 这里要说明一下:sequence在python不是一种特定的类型,而是泛指一系列的类型。 # list, tuple, 字符串都属于sequence。有关sequence可以查看python手册数据模型这一章。 # 下面是使用choice的一些例子: print(random.choice("学习Python"))# print(random.choice(["JGood","is","a","handsome","boy"])) #List print(random.choice(("Tuple","List","Dict"))) #List

    print(random.sample([1,2,3,4,5],3)) #[1, 2, 5] #random.sample的函数原型为:random.sample(sequence, k),从指定序列中随机获取指定长度的片断。sample函数不会修改原有序列。
    import random
    import string
    #随机整数:
    print( random.randint(0,99))  #70
     
    #随机选取0到100间的偶数:
    print(random.randrange(0, 101, 2)) #4
     
    #随机浮点数:
    print( random.random()) #0.2746445568079129
    print(random.uniform(1, 10)) #9.887001463194844
     
    #随机字符:
    print(random.choice('abcdefg&#%^*f')) #f
     
    #多个字符中选取特定数量的字符:
    print(random.sample('abcdefghij',3)) #['f', 'h', 'd']
     
    #随机选取字符串:
    print( random.choice ( ['apple', 'pear', 'peach', 'orange', 'lemon'] )) #apple

    #洗牌# items = [1,2,3,4,5,6,7] print(items) #[1, 2, 3, 4, 5, 6, 7] random.shuffle(items) print(items) #[1, 4, 7, 2, 5, 3, 6]
    import random
    
    check_code=''
    
    for i in range(5):
        current=random.randrange(0,5)
        if current==i:
            tmp=chr(random.randrange(65,90))
        else:
            tmp=random.randint(0,9)
    
        check_code+=str(tmp)
    
    print(check_code)
    随机获取验证码示例

     六、OS模块

    import 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    输出用于分割文件路径的字符串
    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所指向的文件或者目录的最后修改时间

    七、sys模块

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

     八、json&pickle序列化模块

    1、json

    用于序列化的两个模块

    • json   用于字符串和python数据类型间进行转换,json只支持列表,字典这样简单的数据类型 但是它不支持类,函数这样的数据类型转换
    • pickle  它支持所有数据类型 这就是pickle和json的区别,它可以对复杂数据类型做操作,缺点是仅适用于python

    Json模块提供了四个功能:dumps、dump、loads、load

    import json
    
    #dumps和loads只是在内存中转换
    
    dic={'k1':'v1'}
    
    dic1=json.dumps(dic) #将python的基本数据类型转换成字符串形式
    print(type(dic))
    print(type(dic1))
    
    
    s1='{"k2":"v2"}'
    dic2=json.loads(s1)  #将python的字符串形式转换成基本数据类型
    
    print(type(s1))
    print(type(dic2))
    dumps(dict)和loads(str)
    import json
    
    '''json.dump()    具有写文件和读文件的功能
      json.load()
    '''
    li=[11,22,33]
    json.dump(li,open('db','w'))
    
    ret=json.load(open('db','r'))
    print(ret[0])
    print(ret,type(ret))
    dump()和load()

     2、pickle

     pickle模块提供了四个功能:dumps、dump、loads、load

    import pickle
    
    li=[11,22,33]
    
    ret=pickle.dumps(li)
    
    print(ret)  #打印出来的结果是字节码b'x80x03]qx00(Kx0bKx16K!e.'
    
    result=pickle.loads(ret)
    print(result)
    
    
    #pickle支持类,函数这样复杂数据类型的操作
    class foo():
        def __init__(self):
            pass
    
    f=foo()
    ret2=pickle.dumps(f)
    print(ret2)
    
    ret3=pickle.loads(ret2)
    print(ret3)
    dumps&loads
    import pickle
    
    li=[11,22,33]
    
    pickle.dump(li,open('db1','wb'))  #写入文件
    
    ret1=pickle.load(open('db1','rb'))
    
    print(ret1)
    dump()&load()

     3、软件目录结构规范

    设计好目录结构用途:
    
    可读性高: 不熟悉这个项目的代码的人,一眼就能看懂目录结构,知道程序启动脚本是哪个,测试目录在哪儿,配置文件在哪儿等等。从而非常快速的了解这个项目。
    可维护性高: 定义好组织规则后,维护者就能很明确地知道,新增的哪个文件和代码应该放在什么目录之下。这个好处是,随着时间的推移,代码 / 配置的规模增加,项目结构不会混乱,仍然能够组织良好。
    
    
    目录组织方式
    
    关于如何组织一个较好的Python工程目录结构,已经有一些得到了共识的目录结构。在Stackoverflow的这个问题上,能看到大家对Python目录结构的讨论。
    
    Foo /
    | -- bin /
    | | -- foo
    |
    | -- foo /
    | | -- tests /
    | | | -- __init__.py
    | | | -- test_main.py
    | |
    | | -- __init__.py
    | | -- main.py
    |
    | -- docs /
    | | -- conf.py
    | | -- abc.rst
    |
    | -- setup.py
    | -- requirements.txt
    | -- README
    
    简要解释一下:
    
    bin /: 存放项目的一些可执行文件,当然你可以起名script / 之类的也行。
    foo /: 存放项目的所有源代码。(1)
    源代码中的所有模块、包都应该放在此目录。不要置于顶层目录。(2)
    其子目录tests / 存放单元测试代码; (3)
    程序的入口最好命名为main.py。
    docs /: 存放一些文档。
    setup.py: 安装、部署、打包的脚本。
    requirements.txt: 存放软件依赖的外部Python包列表。
    README: 项目说明文件。
    
    
    除此之外,有一些方案给出了更加多的内容。比如LICENSE.txt, ChangeLog.txt文件等,我没有列在这里,因为这些东西主要是项目开源的时候需要用到。如果你想写一个开源软件,目录该如何组织,可以参考这篇文章。
    
    下面,再简单讲一下我对这些目录的理解和个人要求吧。
    
    关于README的内容
    这个我觉得是每个项目都应该有的一个文件,目的是能简要描述该项目的信息,让读者快速了解这个项目。
    
    它需要说明以下几个事项:
    
    软件定位,软件的基本功能。
    运行代码的方法: 安装环境、启动命令等。
    简要的使用说明。
    代码目录结构说明,更详细点可以说明软件的基本原理。
    常见问题说明。
    我觉得有以上几点是比较好的一个README。在软件开发初期,由于开发过程中以上内容可能不明确或者发生变化,并不是一定要在一开始就将所有信息都补全。但是在项目完结的时候,是需要撰写这样的一个文档的。
    
    可以参考Redis源码中Readme的写法,这里面简洁但是清晰的描述了Redis功能和源码结构。
    
    
    
    关于requirements.txt和setup.py
    setup.py
    一般来说,用setup.py来管理代码的打包、安装、部署问题。业界标准的写法是用Python流行的打包工具setuptools来管理这些事情。这种方式普遍应用于开源项目中。不过这里的核心思想不是用标准化的工具来解决这些问题,而是说,一个项目一定要有一个安装部署工具,能快速便捷的在一台新机器上将环境装好、代码部署好和将程序运行起来。
    
    这个我是踩过坑的。
    
    我刚开始接触Python写项目的时候,安装环境、部署代码、运行程序这个过程全是手动完成,遇到过以下问题:
    
    安装环境时经常忘了最近又添加了一个新的Python包,结果一到线上运行,程序就出错了。
    Python包的版本依赖问题,有时候我们程序中使用的是一个版本的Python包,但是官方的已经是最新的包了,通过手动安装就可能装错了。
    如果依赖的包很多的话,一个一个安装这些依赖是很费时的事情。
    新同学开始写项目的时候,将程序跑起来非常麻烦,因为可能经常忘了要怎么安装各种依赖。
    setup.py可以将这些事情自动化起来,提高效率、减少出错的概率。"复杂的东西自动化,能自动化的东西一定要自动化。"
    是一个非常好的习惯。
    
    setuptools的文档比较庞大,刚接触的话,可能不太好找到切入点。学习技术的方式就是看他人是怎么用的,可以参考一下Python的一个Web框架,flask是如何写的: setup.py
    
    当然,简单点自己写个安装脚本(deploy.sh)替代setup.py也未尝不可。
    
    requirements.txt
    这个文件存在的目的是:
    
    方便开发者维护软件的包依赖。将开发过程中新增的包添加进这个列表中,避免在setup.py安装依赖时漏掉软件包。
    方便读者明确项目使用了哪些Python包。
    这个文件的格式是每一行包含一个包依赖的说明,通常是flask >= 0.10
    这种格式,要求是这个格式能被pip识别,这样就可以简单的通过
    pip
    install - r
    requirements.txt来把所有Python包依赖都装好了。具体格式说明: 点这里。
    
    
    
    关于配置文件的使用方法
    注意,在上面的目录结构中,没有将conf.py放在源码目录下,而是放在docs / 目录下。
    很多项目对配置文件的使用做法是:
    
    配置文件写在一个或多个python文件中,比如此处的conf.py。
    项目中哪个模块用到这个配置文件就直接通过import
    conf这种形式来在代码中使用配置。
    这种做法我不太赞同:
    
    这让单元测试变得困难(因为模块内部依赖了外部配置)
    另一方面配置文件作为用户控制程序的接口,应当可以由用户自由指定该文件的路径。
    程序组件可复用性太差,因为这种贯穿所有模块的代码硬编码方式,使得大部分模块都依赖conf.py这个文件。
    所以,我认为配置的使用,更好的方式是,
    
    模块的配置都是可以灵活配置的,不受外部配置文件的影响。
    程序的配置也是可以灵活控制的。
    能够佐证这个思想的是,用过nginx和mysql的同学都知道,nginx、mysql这些程序都可以自由的指定用户配置。
    
    所以,不应当在代码中直接import
    conf来使用配置文件。上面目录结构中的conf.py,是给出的一个配置样例,不是在写死在程序中直接引用的配置文件。可以通过给main.py启动参数指定配置路径的方式来让程序读取配置内容。当然,这里的conf.py你可以换个类似的名字,比如settings.py。或者你也可以使用其他格式的内容来编写配置文件,比如settings.yaml之类的。
    软件目录结构规范

    九、logging模块

     1、默认日志级别和简单应用

    import logging
    
    # 默认日志级别
    NOTSET = 0 #不设置
    DEBUG = 10
    INFO = 20
    WARNING = 30 #WARN = WARNING
    ERROR = 40
    CRITICAL = 50 #FATAL = CRITICAL
    
    
    #调整日志基础设定
    logging.basicConfig(
        level=logging.DEBUG,    # 调整日志级别
        filename='logging.log', # 日志文件
        filemode='w',           # 不追加日志格式,默认为a追加模式
        format="%(asctime)s [%(lineno)d]%(filename)s%(message)s%(threadName)s%(thread)s"  # 日志输出格式
    )
    
    
    logging.debug('调试debug message')
    logging.info('消息info message')
    logging.warning('警告warn message')
    logging.error('错误error message')
    logging.critical('严重critical message')
    logging.basicConfig(
        level=logging.DEBUG,    # 调整日志级别
        filename='logging.log', # 日志文件
        filemode='w',           # 不追加日志格式,默认为a追加模式
        format="%(asctime)s [%(lineno)d]%(filename)s%(message)s%(threadName)s%(thread)s"  # 日志输出格式
    )
    
    #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:用户输出的消息
    logging.basicConfig()设置日志全局配置

     2、logger对象

    #-*-coding:utf-8-*-
    
    import logging
    
    
    def logger(file_name):
    
        logger=logging.getLogger()
    
        logger.setLevel("DEBUG")  # 设置日志级别
        fm=logging.Formatter("%(asctime)s [%(lineno)d]%(filename)s%(message)s%(threadName)s%(thread)s")  #设置日志格式
    
    
        file_log=logging.FileHandler(file_name) # 创建日志写文件对象
        stream_log=logging.StreamHandler()       # 创建日志打印屏幕对象
    
    
        file_log.setFormatter(fm)  # 设置对象日志格式
        stream_log.setFormatter(fm) # 设置对象日志格式
    
    
        logger.addHandler(file_log)
        logger.addHandler(stream_log)
    
        return logger
    
    logger=logger("test.log")
    
    logger.debug('调试debug message')
    logger.info('消息info message')
    logger.warning('警告warn message')
    logger.error('错误error message')
    logger.critical('严重critical message')

     十、configparser模块

    configparser用于处理特定格式的文件,其本质上是利用open来操作文件。

    #指定格式
    
    #注释
    ;注释2
    
    [nick]           #节点
    age = 18         #
    gender = ning    #
    dearm = girl     #
    
    [jenny]          #节点
    age = 21         #
    gender = jia     #

    1、获取所有节点

    import configparser
     
    con = configparser.ConfigParser()
    con.read("ini",encoding="utf-8")
     
    result = con.sections()
    print(result)

    2、获取指定节点下所有的键值对

    import configparser
     
    con = configparser.ConfigParser()
    con.read("ini",encoding="utf-8")
     
    result = con.items("nick")
    print(result)

    3、获取指定节点下所有的键

    import configparser
     
    con = configparser.ConfigParser()
    con.read("ini",encoding="utf-8")
     
    ret = con.options("nick")
    print(ret)

    4、获取指定节点下指定key的值

    import configparser
     
    con = configparser.ConfigParser()
    con.read("ini",encoding="utf-8")
     
    v = con.get("nick","age")
    v = con.get("nick","gender")
    v = con.get("jenny","age")
    v = con.get("jenny","gender")
    print(v)

    5、检查、删除、添加节点

    #检查、删除、添加节点
    import configparser
     
    con = configparser.ConfigParser()
    con.read("ini",encoding="utf-8")
     
    #检查
    has_sec = con.has_section("nick")
    print(has_sec)
     
    #添加节点
    con.add_section("car")
    con.write(open("ini","w"))
     
    #删除节点
    con.remove_section("car")
    con.write(open("ini","w"))

    6、检查、删除、设置指定组内的键值对

    #检查、删除、设置指定组内的键值对
    import configparser
     
    con = configparser.ConfigParser()
    con.read("ini",encoding="utf-8")
     
    #检查
    hac_opt = con.has_option("nick","age")
    print(hac_opt)
     
    #删除
    con.remove_option("nick","dearm")
    con.write(open("ini","w"))
     
    #设置
    con.set("nick","dearm","girl")
    con.write(open("ini","w"))

     shutil模块

    高级的 文件、文件夹、压缩包 处理模块

    #将文件内容拷贝到另一个文件中
    shutil.copyfileobj(fsrc,fdst,length)  
    f1=open('old.xml','r')
    f2=open('new.xml','w')
    
    shutil.copyfileobj(f1,f2)
    shutil.copyfile(src,dst)  #拷贝文件
    
    shutil.copyfile('f1_old.log','f2_new.log')
    shutil.copymode(src, dst)  #仅拷贝权限。内容、组、用户均不变
    shutil.copymode('f1.log', 'f2.log')
    shutil.copystat(src, dst)  #仅拷贝状态的信息,包括:mode bits, atime, mtime, flags  src,dst文件都必须存在
    
    shutil.copystat('f1.log', 'f2.log')
    shutil.copy(src, dst)  #拷贝文件和权限
    shutil.copy('f1.log', 'f2.log')
    shutil.copy2(src, dst) #拷贝文件和状态信息
    shutil.copytree(src, dst, symlinks=False, ignore=None) #递归的去拷贝文件夹
    
    shutil.copytree('folder1', 'folder2', ignore=shutil.ignore_patterns('*.pyc', 'tmp*'))
    shutil.rmtree(path[, ignore_errors[, onerror]]) #递归的去删除文件
    shutil.rmtree('folder1')
    shutil.move(src, dst)  #递归的去移动文件,它类似mv命令,其实就是重命名。
    shutil.make_archive(base_name, format,...)
    
    # 创建压缩包并返回文件路径,例如:zip、tar
    
    # 创建压缩包并返回文件路径,例如:zip、tar
    
    # base_name: 压缩包的文件名,也可以是压缩包的路径。只是文件名时,则保存至当前目录,否则保存至指定路径,
    # 如:www                        =>保存至当前路径
    # 如:/Users/wupeiqi/www =>保存至/Users/wupeiqi/
    # format:    压缩包种类,“zip”, “tar”, “bztar”,“gztar”
    # root_dir:    要压缩的文件夹路径(默认当前目录)
    # owner:    用户,默认当前用户
    # group:    组,默认当前组
    # logger:    用于记录日志,通常是logging.Logger对象
    #将 /Users/wupeiqi/Downloads/test 下的文件打包放置当前程序目录

    import shutil ret = shutil.make_archive("wwwwwwwwww", 'gztar', root_dir='/Users/wupeiqi/Downloads/test') #将 /Users/wupeiqi/Downloads/test 下的文件打包放置 /Users/wupeiqi/目录 import shutil ret = shutil.make_archive("/Users/wupeiqi/wwwwwwwwww", 'gztar', root_dir='/Users/wupeiqi/Downloads/test')

     shutil 对压缩包的处理是调用 ZipFile 和 TarFile 两个模块来进行的,详细:

    import zipfile
    
    # 压缩
    z = zipfile.ZipFile('laxi.zip', 'w')
    z.write('a.log')
    z.write('data.data')
    z.close()
    
    # 解压
    z = zipfile.ZipFile('laxi.zip', 'r')
    z.extractall()
    z.close()
    
    zipfile解压缩
    
    
    import tarfile
    
    # 压缩
    tar = tarfile.open('your.tar','w')
    tar.add('/Users/wupeiqi/PycharmProjects/bbs2.log', arcname='bbs2.log')
    tar.add('/Users/wupeiqi/PycharmProjects/cmdb.log', arcname='cmdb.log')
    tar.close()
    
    # 解压
    tar = tarfile.open('your.tar','r')
    tar.extractall()  # 可设置解压地址
    tar.close()
    
    tarfile解压缩

    hashlib模块

     用于加密相关的操作,3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法

    import hashlib,hmac
    
    m1=hashlib.md5()
    
    m1.update(b"hello")
    
    print(m1.hexdigest())
    m1.update(b"it is me")  #更新 第二次update是与第一次update拼接起来
    
    print(m1.hexdigest())
    
    m2=hashlib.md5()
    
    m2.update(b"helloit is me")
    print(m2.hexdigest())
    
    s1=hashlib.sha1()
    s1.update(b"hello")
    print(s1.hexdigest())
    s1.update(b"it is me")
    print(s1.hexdigest())
    
    s2=hashlib.sha1()
    s2.update(b"helloit is me")
    print(s2.hexdigest())
    
    
    m3=hashlib.md5()
    
    m3.update("天王盖地虎".encode(encoding="utf-8"))
    
    print(m3.hexdigest())
    
    
    
    h=hmac.new("你是二百五".encode(encoding='utf-8'))
    
    print(h.hexdigest())

    paramiko模块

    该模块基于SSH用于连接远程服务器并执行相关操作

    SSHClient

    用于连接远程服务器并执行基本命令

    基于用户名密码连接:

    # -*-coding:utf-8-*-
    # Author:sunhao
    
    import paramiko
    
    ssh= paramiko.SSHClient()   #创建ssh对象
    
    # 允许连接不在know_hosts文件中的主机
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    
    
    #连接服务器
    ssh.connect(hostname='192.168.10.141',port=22,username='root',password='123456')
    
    
    #执行命令
    
    stdin,stdout,stderr=ssh.exec_command("ps aux  ")
    
    #获取命令结果
    result=stdout.read()
    
    print(result.decode())
    
    
    #关闭链接
    ssh.close()

    基于ssh秘钥连接 

    # -*-coding:utf-8-*-
    # Author:sunhao
    
    import  paramiko
    
    private_key = paramiko.RSAKey.from_private_key_file('id_rsa')    #这是192.168.10.141上的私钥
    
    
    
    ssh = paramiko.SSHClient()
    
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    
    ssh.connect(hostname='192.168.10.180',port=22,username='root',pkey=private_key)  #192.168.10.141上的公钥在10.180上放着
    
    
    stdin,stdout,stderr=ssh.exec_command("netstat -lpn;df -h;ps aux |grep ssh")
    
    #获取命令结果
    
    result=stdout.read()
    
    print(result.decode())
    
    
    #关闭链接
    ssh.close()

    SFTPClient

    用于连接远程服务器并执行上传下载

    # -*-coding:utf-8-*-
    # Author:sunhao
    
    import paramiko
    
    transport=paramiko.Transport('192.168.10.141',22)     #远程服务器为192.168.10.141
    
    transport.connect(username='root',password='123456')
    
    sftp = paramiko.SFTPClient.from_transport(transport)
    
    # 将本地paramiko模块-ssh.py 上传至服务器 /tmp/paramiko模块
    
    #sftp.put('paramiko模块-ssh.py', '/home/paramiko模块')
    
    # 将服务器/tmp/zabbix_server.log 下载到本地
    
    sftp.get('/tmp/zabbix_server.log', 'zabbix_server.log')
    
    transport.close()
  • 相关阅读:
    MongoDB面试题
    spider 爬虫文件基本参数(3)
    命令行工具(2)
    初始scrapy,简单项目创建和CSS选择器,xpath选择器(1)
    数据分析实例(离海洋距离与最高温度之间的关系分析)
    路飞业务分析
    MYSQL 主从复制,读写分离(8)
    pyquery 学习
    selenium case报错重新执行
    python小技巧
  • 原文地址:https://www.cnblogs.com/sunhao96/p/7698843.html
Copyright © 2020-2023  润新知