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.自定义模块

Python全栈开发之5、模块

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

Python全栈开发之5、模块

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

Python全栈开发之5、模块

#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

Python全栈开发之5、模块

三、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 时区的名字(如果不存在为空字符)
%% ‘%’字符

Python全栈开发之5、模块

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工程目录结构,已经有一些得到了共识的目录结构。在*的这个问题上,能看到大家对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()
上一篇:c语言输入输出函数


下一篇:EF使用sql语句