Day6-python基础之模块

时间:2022-11-11 16:46:24

模块,用一砣代码实现了某个功能的代码集合。

类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合。而对于一个复杂的功能来,可能需要多个函数才能完成(函数又可以在不同的.py文件中),n个 .py 文件组成的代码集合就称为模块。

如:os 是系统相关的模块;file是文件操作相关的模块

模块分为三种:

  • 自定义模块
  • 内置标准模块(又称标准库)
  • 开源模块

开源模块

一、下载安装

下载安装有两种方式:

1.

yum
pip
apt-get

2.

下载源码
解压源码
进入目录
编译源码 python setup.py build
安装源码 python setup.py install

注:在使用源码安装时,需要使用到gcc编译和python开发环境,所以,需要先执行:

yum install gcc

yum install python-devel
apt-get python-dev
内置模块
time&datetime模块
import time
print(time.altzone)#返回与utc时间的时间差,以秒计算
print(time.asctime())#返回时间格式
print(time.localtime())#返回本地时间的时间对象
print(time.asctime(time.localtime())) t2 = time.strptime("2016-11-11 23:30","%Y-%m-%d %H:%M")#将日期字符串转换struct时间对象格式
t2_stamp = time.mktime(t2)#将struct时间对象转成时间戳
print(t2_stamp) t3 = time.localtime(t2_stamp) #stamp to time struct
t3_str = time.strftime("%Y_%m_%d.log", t3)#将utc struct_time格式转成指定的字符串格式
print(t3_str) import time
import datetime
print(datetime.datetime.now())
print(datetime.date.fromtimestamp(time.time()))#时间戳转成日期格式
print(datetime.datetime.now()+datetime.timedelta(3))#时间加3天
print(datetime.datetime.now()+datetime.timedelta(hours=3))#时间加3小时
now = datetime.datetime.now()
print(now.timetuple())#时间对象

random模块

import random
import string
print(random.random())
print(random.randint(0,5))#0-5之间随机产生
print(random.randrange(0,5))#0-4之间随机产生 str_source = string.ascii_letters + string.digits
print(''.join(random.sample(str_source,5)))#随机生成5位a-zA-Z0-9

生成随机验证码

import random
checkcode = ''
for i in range(4):
current = random.randrange(0,4)
if current != i:
temp = chr(random.randint(65,90))
else:
temp = random.randint(0,9)
checkcode += str(temp)
print(checkcode)

shutil

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

import shutil
f1 = open("random mod.py")
f2 = open("random_new.py","w")
shutil.copyfileobj(f1,f2) shutil.copy(r"C:\Users\Administrator\PycharmProjects\py_s15\day3\笔记","test")#拷贝文件和权限
shutil.copy2()#拷贝文件和状态信息
shutil.copyfile()
shutil.copytree(r"C:\Users\Administrator\PycharmProjects\py_s15\day3","day3_new")#递归去拷贝文件 shutil.make_archive(r"c:\day3",format="zip",root_dir=r"C:\Users\Administrator\PycharmProjects\py_s15\day3")#创建压缩包并返回文件路劲 #对压缩包的处理调用zipfile和tarfile处理
import zipfile
zip_obj = zipfile.ZipFile(r"c:\zip_test.zip","w")
zip_obj.write("test")
zip_obj.write(r"C:\Users\Administrator\PycharmProjects\py_s15\day3")#把test和C:\Users\Administrator\PycharmProjects\py_s15\day3压缩到c:\zip_test.zip
zip_obj.close() import tarfile
EXCLUDE_FILES = ['字典', '笔记', 'lyrics']
def exclude_function(tarinfo):
if tarinfo.name in EXCLUDE_FILES and tarinfo.isdir():
print("filter...")
return None
else:
return tarinfo tar = tarfile.open(r'c:\your.tar','w')
tar.add(r"C:\Users\Administrator\PycharmProjects\py_s15\day3",filter=exclude_function,arcname="alex")
tar.add(r"c:\zip_test.zip")
tar.close()

shelve模块

shelve模块是一个简单的k,v将内存数据通过文件持久化的模块,可以持久化任何pickle可支持的python数据格式

import shelve
d = shelve.open('shelve_test')
def stu_data(name,age):
print('register stu',name,age)
name = ['alex','rain','test']
info = {'name':'alex','age':22}
d['test'] = name
d['info'] = info
d['func'] = stu_data

xml处理模块

xml的格式如下,就是通过<>节点来区别数据结构的:

<?xml version="1.0"?>
<data>
<country name="Liechtenstein">
<rank updated="yes">2</rank>
<year>2008</year>
<gdppc>141100</gdppc>
<neighbor name="Austria" direction="E"/>
<neighbor name="Switzerland" direction="W"/>
</country>
<country name="Singapore">
<rank updated="yes">5</rank>
<year>2011</year>
<gdppc>59900</gdppc>
<neighbor name="Malaysia" direction="N"/>
</country>
<country name="Panama">
<rank updated="yes">69</rank>
<year>2011</year>
<gdppc>13600</gdppc>
<neighbor name="Costa Rica" direction="W"/>
<neighbor name="Colombia" direction="E"/>
</country>
</data>

xml协议在各个语言里的都 是支持的,在python中可以用以下模块操作xml

import xml.etree.ElementTree as ET

tree = ET.parse("xmltest.xml")
root = tree.getroot()
print(root.tag) #遍历xml文档
for child in root:
print(child.tag, child.attrib)
for i in child:
print(i.tag,i.text) #只遍历year 节点
for node in root.iter('year'):
print(node.tag,node.text)

ConfigParser模块

用于生成和修改常见配置文档,当前模块的名称在 python 3.x 版本中变更为 configparser。

import configparser

config = configparser.ConfigParser()
config["DEFAULT"] = {'ServerAliveInterval': '',
'Compression': 'yes',
'CompressionLevel': ''} config['bitbucket.org'] = {}
config['bitbucket.org']['User'] = 'hg'
config['topsecret.server.com'] = {}
topsecret = config['topsecret.server.com']
topsecret['Host Port'] = '' # mutates the parser
topsecret['ForwardX11'] = 'no' # same here
config['DEFAULT']['ForwardX11'] = 'yes'
with open('example.ini', 'w') as configfile:
config.write(configfile)

hashlib模块 

import hashlib

m = hashlib.md5()
m.update(b"Hello")
m.update(b"It's me")
print(m.digest())
m.update(b"It's been a long time since last time we ...") print(m.digest()) #2进制格式hash
print(len(m.hexdigest())) #16进制格式hash
'''
def digest(self, *args, **kwargs): # real signature unknown
""" Return the digest value as a string of binary data. """
pass def hexdigest(self, *args, **kwargs): # real signature unknown
""" Return the digest value as a string of hexadecimal digits. """
pass '''
import hashlib # ######## md5 ######## hash = hashlib.md5()
hash.update('admin')
print(hash.hexdigest()) # ######## sha1 ######## hash = hashlib.sha1()
hash.update('admin')
print(hash.hexdigest()) # ######## sha256 ######## hash = hashlib.sha256()
hash.update('admin')
print(hash.hexdigest()) # ######## sha384 ######## hash = hashlib.sha384()
hash.update('admin')
print(hash.hexdigest()) # ######## sha512 ######## hash = hashlib.sha512()
hash.update('admin')
print(hash.hexdigest())

logging模块

很多程序都有记录日志的需求,并且日志中包含的信息即有正常的程序访问日志,还可能有错误、警告等信息输出,python的logging模块提供了标准的日志接口,你可以通过它存储各种格式的日志,logging的日志可以分为 debug()info()warning()error() and critical() 5个级别,下面我们看一下怎么用。

import logging

logging.warning("user [alex] attempted wrong password more than 3 times")
logging.critical("server is down") #输出
WARNING:root:user [alex] attempted wrong password more than 3 times
CRITICAL:root:server is down

日志写到文件中

import logging

logging.basicConfig(filename='example.log',level=logging.INFO)
logging.debug('This message should go to the log file')
logging.info('So should this')
logging.warning('And this, too')

其中下面这句中的level=loggin.INFO意思是,把日志纪录级别设置为INFO,也就是说,只有比日志是INFO或比INFO级别更高的日志才会被纪录到文件里

日志格式

%(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

用户输出的消息

如果想同时把log打印在屏幕和文件日志里

import logging

#create logger
logger = logging.getLogger('TEST-LOG')
logger.setLevel(logging.DEBUG) # create console handler and set level to debug
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG) # create file handler and set level to warning
fh = logging.FileHandler("access.log")
fh.setLevel(logging.WARNING)
# create formatter
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') # add formatter to ch and fh
ch.setFormatter(formatter)
fh.setFormatter(formatter) # add ch and fh to logger
logger.addHandler(ch)
logger.addHandler(fh) # 'application' code
logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')

文件自动截断

import logging

from logging import handlers

logger = logging.getLogger(__name__)

log_file = "timelog.log"
#fh = handlers.RotatingFileHandler(filename=log_file,maxBytes=10,backupCount=3)
fh = handlers.TimedRotatingFileHandler(filename=log_file,when="S",interval=5,backupCount=3) formatter = logging.Formatter('%(asctime)s %(module)s:%(lineno)d %(message)s') fh.setFormatter(formatter) logger.addHandler(fh) logger.warning("test1")
logger.warning("test12")
logger.warning("test13")
logger.warning("test14")

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 匹配包含
re.findall 把所有匹配到的字符放到以列表中的元素返回
re.splitall 以匹配到的字符当做列表分隔符
re.sub 匹配字符并替换

subprocess模块

os.system输出命令结果到屏幕,返回命令执行状态

os.popen('dir').read()会保存命令的执行结果输出

常用方法

1.subprocess.run(['df -h'],shell = True)

2.#接收字符串格式命令,返回元组形式,第1个元素是执行状态,第2个是命令结果 
>>> subprocess.getstatusoutput('ls /bin/ls')
(0, '/bin/ls')

stdin 标准输入

stdout 标准输出

stderr 标准错误

3.>>> p = subprocess.Popen("df -h|grep disk",stdin=subprocess.PIPE,stdout=subprocess.PIPE,shell=True)
>>> p.stdout.read()
b'/dev/disk1 465Gi 64Gi 400Gi 14% 16901472 104938142 14% /\n'

 
optparse模块
用来检测用户输入的命令参数合法性
parser = optparse.OptionParser()
parser.add_option("-s","--server", dest="server", help="ftp server ip_addr")
parser.add_option("-P","--port",type="int", dest="port", help="ftp server port")
parser.add_option("-u","--username", dest="username", help="username")
parser.add_option("-p","--password", dest="password", help="password")
self.options , self.args = parser.parse_args()
optparse模块的一个坑
python3 command.py -s bj02-ops-git.gomeplus.com,test -g test -c "df -h"
像输入这种命令,一定要加上双引号,单引号或者不加都会报错,会认为是输入的一个参数
 
python3 ftp_client.py -s localhost -P22 -u alex -p ds start
options和args的值{'username': 'alex', 'port': 22, 'password': 'ds', 'server': 'localhost'} ['start']
虽然看起来是字典的格式,但是只能用options.username,options.port这样来取值。