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()。下面列出这种方式元组中的几个元素:
- # -*-coding:utf-8-*-
- import time
- print(time.time()) #获取一个时间戳 从1970年开始按秒计时的一个浮点型数值
- print(time.localtime()) #返回一个struct_time元组类型序列 里面元素包含年,月,日等九个元素
- print(time.timezone) #返回一个值 单位为秒
- print(time.asctime()) #返回当前时间字符串格式
- time.sleep(2) #睡眠几秒
- time.gmtime() #把时间戳转换成元组,但是时间是UTC时间
- time.gmtime(time.time()-time.timezone) #把UTC时间转换成当地时间
- 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模块(正则表达式)
- '.' 默认匹配除\n之外的任意一个字符,若指定flag DOTALL,则匹配任意字符,包括换行
- '^' 匹配字符开头,若指定flags MULTILINE,这种也可以匹配上(r"^a","\nabc\neee",flags=re.MULTILINE)
- '$' 匹配字符结尾,或e.search("foo$","bfoo\nsdfsf",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") 是匹配不到的
- '\Z' 匹配字符结尾,同$
- '\d' 匹配数字0-9
- '\D' 匹配非数字
- '\w' 匹配[A-Za-z0-9]
- '\W' 匹配非[A-Za-z0-9]
- '\s' 匹配空白字符、\t、\n、\r , re.search("\s+","ab\tc1\n3").group() 结果 '\t'
- '(?P<name>...)' 分组匹配 re.search("(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{4})","").groupdict("city") 结果{'province': '', 'city': '', 'birthday': ''}
常用正则表达式符号
- 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)) #
- #random.randint()的函数原型为:random.randint(a, b),用于生成一个指定范围内的整数。
- # 其中参数a是下限,参数b是上限,生成的随机数n: a <= n <= b
- print (random.randrange(1,10)) #
- #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)) #
- #随机选取0到100间的偶数:
- print(random.randrange(0, 101, 2)) #
- #随机浮点数:
- 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下为"\t\n",Linux下为"\n"
- 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'\x80\x03]q\x00(K\x0bK\x16K!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='')
- #执行命令
- 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='')
- 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()
Python全栈开发之5、模块的更多相关文章
- python全栈开发之OS模块的总结
OS模块 1. os.name() 获取当前的系统 2.os.getcwd #获取当前的工作目录 import os cwd=os.getcwd() # dir=os.listdi ...
- 战争热诚的python全栈开发之路
从学习python开始,一直是自己摸索,但是时间不等人啊,所以自己为了节省时间,决定报个班系统学习,下面整理的文章都是自己学习后,认为重要的需要弄懂的知识点,做出链接,一方面是为了自己找的话方便,一方 ...
- Python全栈开发之MySQL(二)------navicate和python操作MySQL
一:Navicate的安装 1.什么是navicate? Navicat是一套快速.可靠并价格相宜的数据库管理工具,专为简化数据库的管理及降低系统管理成本而设.它的设计符合数据库管理员.开发人员及中小 ...
- Python全栈开发之14、Javascript
一.简介 前面我们学习了html和css,但是我们写的网页不能动起来,如果我们需要网页出现各种效果,那么我们就要学习一门新的语言了,那就是JavaScript,JavaScript是世界上最流行的脚本 ...
- Python全栈开发之1、输入输出与流程控制
Python简介 python是吉多·范罗苏姆发明的一种面向对象的脚本语言,可能有些人不知道面向对象和脚本具体是什么意思,但是对于一个初学者来说,现在并不需要明白.大家都知道,当下全栈工程师的概念很火 ...
- Python全栈开发之5、几种常见的排序算法以及collections模块提供的数据结构
转载请注明出处http://www.cnblogs.com/Wxtrkbc/p/5492298.html 在面试中,经常会遇到一些考排序算法的题,在这里,我就简单了列举了几种最常见的排序算法供大家学习 ...
- Python全栈开发之7、模块和几种常见模块以及format知识补充
一.模块的分类 Python流行的一个原因就是因为它的第三方模块数量巨大,我们编写代码不必从零开始重新造轮子,许多要用的功能都已经写好封装成库了,我们只要直接调用即可,模块分为内建模块.自定义的模块. ...
- Python全栈开发之21、django
http://www.cnblogs.com/wupeiqi/articles/5237704.html http://www.cnblogs.com/wupeiqi/articles/5246483 ...
- python全栈开发之路
一.Python基础 python简介 python数据类型(数字\字符串\列表) python数据类型(元组\字典) python数据类型(集合) python占位符%s,%d,%r,%f prin ...
随机推荐
- Luogu P2602 [ZJOI2010]数字计数 数位DP
很久以前就...但是一直咕咕咕 思路:数位$DP$ 提交:1次 题解:见代码 #include<cstdio> #include<iostream> #include<c ...
- apply, bind, call--绑定this的方法
Function.prototype.call(),Function.prototype.apply(),Function.prototype.bind() 是三种改变函数内部this指向(即函数执行 ...
- luogu SP8093 后缀自动机+树状数组+dfs序
这题解法很多,简单说几个: 1. 线段树合并,时间复杂度是 $O(nlog^2n)$ 的. 2. 暴力跳 $fail,$ 时间复杂度 $O(n\sqrt n),$ 比较暴力. 3. 建立后缀树后在 $ ...
- 树莓派安装alsa-lib库
安装alsa-lib库 apt-get install libasound2-dev dpkg -L libasound2-dev 参考:https://blog.csdn.net/happygril ...
- thinkphp6下载安装与配置图文详细讲解教程(composer下载安装)
thinkphp6发布也有一段时间了,相对来说比较稳定,是时候学习一下thinkphp6框架,提前学习,到正式发布的时候,可以直接拿来做正式的项目,先人一步.thinkPHP6.0在5.1的基础上对底 ...
- JavaWeb_(Hibernate框架)Hibernate论坛项目中一对多案例
基于SSH论坛小型项目 传送门 用户和发帖进行举例 一对多关系:一个用户可以发表多个帖子 一对一关系:一个帖子属于一个用户发布 创建数据库用户user表 CREATE TABLE `hforum`.` ...
- 国产手机的谷X服务
我换了个新手机,但面临了一个棘手的问题,就是原来的手机的谷X服务是用免root安装器自动安装好的,安装器找不到了.而后我发现现在的手机并没有阉割掉谷X服务,原因不详,好处不用在去一个个安装了.我装好y ...
- 03 HTTP协议与HTTPS协议
一.HTTP协议 1.官方概念: HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文 ...
- js 中null,undefined区别
首先摘自阮一峰先生的文章: 大多数计算机语言,有且仅有一个表示"无"的值,比如,C语言的NULL,Java语言的null,Python语言的None,Ruby语言的nil. 有点奇 ...
- Linux设备驱动程序 之 自旋锁
概念 自旋锁可以再不能休眠的代码中使用,比如中断处理例程:在正确使用的情况下,自旋锁通常可以提供比信号量更高的性能: 一个自旋锁是一个互斥设备,它只能由两个值,锁定和解锁:通常实现为某个整数值中的单个 ...