一、模块
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))
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))
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)
import pickle li=[11,22,33] pickle.dump(li,open('db1','wb')) #写入文件 ret1=pickle.load(open('db1','rb')) print(ret1)
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:用户输出的消息
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()