本节大纲


  1. 模块介绍
  2. time &datetime模块
  3. random
  4. os
  5. sys
  6. shutil
  7. json & picle
  8. shelve
  9. xml处理
  10. yaml处理
  11. configparser
  12. hashlib
  13. subprocess
  14. logging模块
  15. re正则表达式

1:模块介绍

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

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

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

模块分为三种:

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

模块导入的三种方式:

方法一:

import modname 

用import语句导入模块,就在当前的名称空间(namespace)建立了一个到该模块的引用.这种引用必须使用全称,也就是说,当使用在被导入模块中定义的函数时,必须包含模块的名字。所以不能只使用 funcname,而应该使用 modname.funcname

方法二:

from modname import funcname
from modname import fa, fb, fc
from modname import *

与第1种方法的区别:funcname 被直接导入到本地名字空间去了,所以它可以直接使用,而不需要加上模块名的限定* 表示,该模块的所有公共对象(public objects)都被导入到 当前的名称空间,也就是任何只要不是以”_”开始的东西都会被导入。 
       modname没有被定义,所以modname.funcname这种方式不起作用。并且,如果funcname如果已经被定义,它会被新版本(该导入模块中的版本)所替代。如果funcname被改成指向其他对象,modname不能不会觉察到。 
建议:

  1. 如果你要经常访问模块的属性和方法,且不想一遍又一遍地敲入模块名,使用 from module import
  2. 如果你想要有选择地导入某些属性和方法,而不想要其它的,使用 from module import
  3. 如果模块包含的属性和方法与你的某个模块同名,你必须使用import module来避免名字冲突
  4. 尽量少用 from module import * ,因为判定一个特殊的函数或属性是从哪来的有些困难,并且会造成调试和重构都更困难。

2:time & datetime模块

 #_*_coding:utf-8_*_
__author__ = 'Alex Li' import time # print(time.clock()) #返回处理器时间,3.3开始已废弃 , 改成了time.process_time()测量处理器运算时间,不包括sleep时间,不稳定,mac上测不出来
# print(time.altzone) #返回与utc时间的时间差,以秒计算\
# print(time.asctime()) #返回时间格式"Fri Aug 19 11:14:16 2016",
# print(time.localtime()) #返回本地时间 的struct time对象格式
# print(time.gmtime(time.time()-800000)) #返回utc时间的struc时间对象格式 # print(time.asctime(time.localtime())) #返回时间格式"Fri Aug 19 11:14:16 2016",
#print(time.ctime()) #返回Fri Aug 19 12:38:29 2016 格式, 同上 # 日期字符串 转成 时间戳
# string_2_struct = time.strptime("2016/05/22","%Y/%m/%d") #将 日期字符串 转成 struct时间对象格式
# print(string_2_struct)
# #
# struct_2_stamp = time.mktime(string_2_struct) #将struct时间对象转成时间戳
# print(struct_2_stamp) #将时间戳转为字符串格式
# print(time.gmtime(time.time()-86640)) #将utc时间戳转换成struct_time格式
# print(time.strftime("%Y-%m-%d %H:%M:%S",time.gmtime()) ) #将utc struct_time格式转成指定的字符串格式 #时间加减
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)) #时间替换

3:random

import random

print(random.random())
print(random.randint(1, 2))
print(random.randrange(1, 10))

4:OS模块

用于提供系统级别的操作:

os.getcwd()                 获取当前工作目录,即当前python脚本工作的目录路径
os.chdir("dirname") 改变当前脚本工作目录;相当于shell下cd
os.curdir 返回当前目录: ('.')
os.pardir 获取当前目录的父目录字符串名:('..')
os.makedirs('dir1/dir2') 可生成多层递归目录
os.removedirs('dirname1') 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
os.mkdir('dirname') 生成单级目录;相当于shell中mkdir dirname
os.rmdir('dirname') 删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
os.listdir('dirname') 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
os.remove() 删除一个文件
os.rename("oldname","new") 重命名文件/目录
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所指向的文件或者目录的最后修改时间

5:sys模块

sys模块用于提供对python解释器相关的操作:

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

练习题:

1:读写用户的输入,根据用户输入,创建一个相应的目录

import sys,os
print(sys.argv)
os.mkdir(sys.argv[1])

在命令行下执行:

D:\Python\Python35-32>python e:/wwwroot/py
['e:/wwwroot/python/index.py', 'testdir']

执行完毕,在D:\Python\Python35-32目录下就多了一个testdir的目录

2:自己写一个简单的脚本,可以在任何路径导入

3:进度条,带百分比

 import sys,time
for i in range(31):
sys.stdout.write('\r')
sys.stdout.write("%s%% |%s" % (int(i/30*100),int(i/30*100)*'*'))
sys.stdout.flush()
time.sleep(0.1)

如何添加sys.path路径:

import sys
sys.path.append("D:")#这里写需要添加的路径
for i in sys.path:
print(i)

6:shuntil

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

shutil.copyfileobj(fsrc, fdst[, length]):将文件内容拷贝到另一个文件中

 import shutil

 shutil.copyfileobj(open('old.xml','r'), open('new.xml', 'w'))

shutil.copyfile(src, dst):拷贝文件

shutil.copyfile('f1.log', 'f2.log')

shutil.copymode(src, dst):仅拷贝权限。内容、组、用户均不变

shutil.copymode('f1.log', 'f2.log')

shutil.copystat(src, dst):仅拷贝状态的信息,包括:mode bits, atime, mtime, flags

shutil.copystat('f1.log', 'f2.log')

shutil.copy(src, dst):拷贝文件和权限

import shutil

shutil.copy('f1.log', 'f2.log')

shutil.copy2(src, dst):拷贝文件和状态信息

import shutil

shutil.copy2('f1.log', 'f2.log')

shutil.ignore_patterns(*patterns)
shutil.copytree(src, dst, symlinks=False, ignore=None)
递归的去拷贝文件夹

import shutil

shutil.copytree('folder1', 'folder2', ignore=shutil.ignore_patterns('*.pyc', 'tmp*'))
import shutil

shutil.copytree('f1', 'f2', symlinks=True, ignore=shutil.ignore_patterns('*.pyc', 'tmp*'))

shutil.rmtree(path[, ignore_errors[, onerror]])
递归的去删除文件

import shutil

shutil.rmtree('folder1')

shutil.move(src, dst)
递归的去移动文件,它类似mv命令,其实就是重命名。

import shutil

shutil.move('folder1', 'folder3')

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解压缩

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解压缩

tarfile解压缩

7:json & pickle 模块

用于序列化的两个模块

  • json,用于字符串 和 python数据类型间进行转换
  • pickle,用于python特有的类型 和 python的数据类型间进行转换

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

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

pickle模块的dumps,loads演示:

假如现在有一个字典弄的数据,内容如下:

accounts = {
1000:{
'name':'poe',
'password':'',
'email':'ginvip@qq.com',
'balance':15000,
'phone':13888888888,
'back_acc':{'ICBC':62202,'CBC':52202,'ABC':42202}
},
1001:{
'name':'jet',
'password':'',
'email':'jet@qq.com',
'balance':150,
'phone':13888888888,
'back_acc':{'ICBC':62202}
}
}

那么如何将这个字典型的数据持久化保存到硬盘里呢?由于文件的写入只允许保存字符串,所以一般的方法无法将该字典型数据保存到硬盘里,这里就需要用到pickle模块的dumps与loads功能

 import pickle
accounts = {
1000:{
'name':'poe',
'password':'',
'email':'ginvip@qq.com',
'balance':15000,
'phone':13888888888,
'back_acc':{'ICBC':62202,'CBC':52202,'ABC':42202}
},
1001:{
'name':'jet',
'password':'',
'email':'jet@qq.com',
'balance':150,
'phone':13888888888,
'back_acc':{'ICBC':62202}
}
}
f = open('account.db','wb')
f.write(pickle.dumps(accounts))
f.close()

account.py

数据保存后,那么如果需要重写,该怎么办呢?

 import pickle
acc_file_name = "account.db"
account_file = open(acc_file_name,'rb')
# print(pickle.loads(account_file.read()))
account_dic = pickle.loads(account_file.read())
account_file.close()
account_dic[1000]['balance'] -= 500
f = open(acc_file_name,'wb')
f.write(pickle.dumps(account_dic))
f.close()
print(account_dic)

shopping.py

验证数据是否写入成功:

import pickle
f = open("account.db",'rb') account_db = pickle.loads(f.read())
print(account_db)

check.py

 import json
s = '{"key1":"value1","key2":"value2"}' # ==> 用json模块将字符串转化成其他数据类型,字符串里出现引号必须用双引号
ret = json.loads(s) # ==> loads 由字符串转其他数据类型
print(ret,type(ret)) ret = json.load(open('ethan.txt','r')) # ==> 将文档(内部是字符串格式)转换成python的其他数据类型
print(ret,type(ret)) # ==> 文档里是字典样式的字符串 l = '[11,22,3,56,75]'
result =json.loads(l)
print(result,type(result))
# 总结:
# json.loads()用于将形似字典、列表、元组的字符串,转换成字典、列表、元组
# json.load() 用于将文档(内容是形似字典、列表、元组的字符串)转换成字典、列表、元组 di = {"key1":"value1","key2":"value2"}
ret = json.dumps(di) # ==> 将字典、列表、元组 转换成字符串格式
print(ret,type(ret)) json.dump(di,open('ethan.txt','a+')) # ==> 将字典、元组、列表转换成字符串格式并写入文档 import pickle d = {'name':'ethan','age':28}
ret = pickle.dumps(d) # ==> pickle将字典、元组、列表转换成二进制
print(ret,type(ret)) l = [11,22,3,45,54]
res = pickle.dumps(l)
print(res) pickle.dump(d,open('ethan.txt','ab')) # ==> 将字典、元组、列表转换成二进制写入文档 # 注意 dump load 不要一起运行,会报错,一步一步来 f = open('ethan.txt','rb')
r = pickle.loads(f.read()) # ==> 将二进制转换成字典、列表、元组
print(r)

11:configpaser模块

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

 # 注释1
; 注释2 [section1] # 节点
k1 = v1 # 值
k2:v2 # 值 [section2] # 节点
k1 = v1 # 值 指定格式

指定格式

举例:假如现在有一个ini的文件,内容如下:

 [poe]
age = 12
gender = 'female'
edu = 'daxue'
[jet]
age = 19
gender = 'male'

1:利用configparser模块提供的功能,获取所有节点

import configparser
con = configparser.ConfigParser()#创建对象
#con对象的read功能,打开文件读取文件,放进内存
con.read("ini",encoding="utf-8")
#con对象的sections,内在中寻找所有的[xxx]节点
result = con.sections()
print(result)
#con对象的options功能,获取指定[xxx]节点下的内容
ret = con.options("poe")
print(ret)
##########################################
['poe', 'jet']
['age', 'gender', 'edu']

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

import configparser
con = configparser.ConfigParser()
con.read("ini",encoding="utf-8") ret = con.items('poe')
print(ret)
##########################################
[('age', ''), ('gender', "'female'"), ('edu', "'daxue'")]

3:获取指定节点下指定key的值

import configparser
con = configparser.ConfigParser()
con.read("ini",encoding="utf-8") ret = con.get("poe","age")
print(ret)
##########################################
12

4:检查、删除、添加节点

 import configparser
con = configparser.ConfigParser()
con.read("ini",encoding="utf-8") # 检查节点是否存在,存在返回True,否则返回False
has_sec = con.has_section("poe")
print(has_sec) # 添加节点
con.add_section("andy")
con.write(open("ini","w")) # 删除节点
con.remove_section("trim")
con.write(open("ini","w"))

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

 import configparser
con = configparser.ConfigParser()
con.read("ini",encoding="utf-8") # 检查andy节点下是否存在hobby键
has_sec = con.has_option("andy","hobby")
print(has_sec) # 删除
con.remove_option("andy","hobby")
con.write(open("ini","w")) # 设置
con.set("andy","from","beijing")
con.write(open("ini","w"))

总结:

增:

  1. obj.add_section(块节点名称)   增加一个块节点
  2. obj.set(块节点名称,键,值)         在指定的块节点下增加键值

删:

  1. obj.remove_section(块节点名称)             删除指定块节点(连同该块节点下的所有键值都删除)
  2. obj.remove_option(块节点名称,该块节点下的键名)             删除指定块节点下指定键的键值对

改:

  1. obj.set(块节点名称,键,值)

查:

  1. obj.sections()                 查询所有的块节点(且称之为块节点,如:上面文件中的[poe],[jet]),返回一个列表
  2. obj.options(块节点名称)              查询指定块节点下的所有键,返回一个列表
  3. obj.items(块节点名称)                 查询指定块节点下的所有键及值,返回一个列表(每个键值对保存为一个元组)
  4. obj.get(块节点名称,块节点下的键)                      查询指定块节点下,键所对就的值
  5. obj.has_section(块节点名称)                                查询块节点是否存在
  6. obj.has_option(块节点名称,块节点下的键)        查询指定块节点下的键是否存在

12:hashlib

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

import hashlib

# ######## md5 ########
hash = hashlib.md5()
# help(hash.update)
hash.update(bytes('admin', encoding='utf-8'))
print(hash.hexdigest())
print(hash.digest()) ######## sha1 ######## hash = hashlib.sha1()
hash.update(bytes('admin', encoding='utf-8'))
print(hash.hexdigest()) # ######## sha256 ######## hash = hashlib.sha256()
hash.update(bytes('admin', encoding='utf-8'))
print(hash.hexdigest()) # ######## sha384 ######## hash = hashlib.sha384()
hash.update(bytes('admin', encoding='utf-8'))
print(hash.hexdigest()) # ######## sha512 ######## hash = hashlib.sha512()
hash.update(bytes('admin', encoding='utf-8'))
print(hash.hexdigest())

以上加密算法虽然依然非常厉害,但时候存在缺陷,即:通过撞库可以反解。所以,有必要对加密算法中添加自定义key再来做加密。(推荐使用此方法)

import hashlib

# ######## md5 ########

hash = hashlib.md5(bytes('898oaFs09f',encoding="utf-8"))
hash.update(bytes('admin',encoding="utf-8"))
print(hash.hexdigest())

python内置还有一个 hmac 模块,它内部对我们创建 key 和 内容 进行进一步的处理然后再加密

import hmac

h = hmac.new(bytes('898oaFs09f',encoding="utf-8"))
h.update(bytes('admin',encoding="utf-8"))
print(h.hexdigest())

基于加密的登录程序:

import hashlib
def md5(arg) :
p = hashlib.md5(bytes('admin',encoding='utf-8'))
p.update(bytes(arg,encoding='utf-8'))
return p.hexdigest() def register(user,pwd) :
with open("db","a",encoding="utf-8") as f :
temp = user + "|" + md5(pwd)
f.write(temp)
def login(user,pwd):
with open('db','r',encoding="utf-8") as f :
for line in f:
u,p = line.strip().split("|")
if u == user and p == md5(pwd):
return True
return False
i = input("1:login 2:register")
if i == '':
user = input('username : ')
pwd = input('password : ')
register(user,pwd)
elif i == '':
user = input('username :')
pwd = input('password :')
if login(user,pwd) :
print('login success')
else:
print('login failed')

用户登录

13:subprocess模块

执行shell命令

call 

执行命令,返回状态码

ret = subprocess.call(["ls", "-l"], shell=False)
ret = subprocess.call("ls -l", shell=True)

check_call

执行命令,如果执行状态码是 0 ,则返回0,否则抛异常

subprocess.check_call(["ls", "-l"])
subprocess.check_call("exit 1", shell=True)

check_output

执行命令,如果状态码是 0 ,则返回执行结果,否则抛异常

subprocess.check_output(["echo", "Hello World!"])
subprocess.check_output("exit 1", shell=True)

subprocess.Popen(...)

用于执行复杂的系统命令

参数:

  1. args:shell命令,可以是字符串或者序列类型(如:list,元组)
  2. bufsize:指定缓冲。0 无缓冲,1 行缓冲,其他 缓冲区大小,负值 系统缓冲
  3. stdin, stdout, stderr:分别表示程序的标准输入、输出、错误句柄
  4. preexec_fn:只在Unix平台下有效,用于指定一个可执行对象(callable object),它将在子进程运行之前被调用
  5. close_sfs:在windows平台下,如果close_fds被设置为True,则新创建的子进程将不会继承父进程的输入、输出、错误管道。
  6. 所以不能将close_fds设置为True同时重定向子进程的标准输入、输出与错误(stdin, stdout, stderr)。
  7. shell:同上
  8. cwd:用于设置子进程的当前目录
  9. env:用于指定子进程的环境变量。如果env = None,子进程的环境变量将从父进程中继承。
  10. universal_newlines:不同系统的换行符不同,True -> 同意使用 \n
  11. startupinfo与createionflags只在windows下有效
  12. 将被传递给底层的CreateProcess()函数,用于设置子进程的一些属性,如:主窗口的外观,进程的优先级等等
import subprocess
ret1 = subprocess.Popen(["mkdir","t1"])
ret2 = subprocess.Popen("mkdir t2", shell=True)

终端输入的命令分为两种:

  1. 输入即可得到输出,如:ifconfig
  2. 输入进行某环境,依赖再输入,如:python
import subprocess

obj = subprocess.Popen("mkdir t3", shell=True, cwd='/home/dev',)
import subprocess

obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
obj.stdin.write("print(1)\n")
obj.stdin.write("print(2)")
obj.stdin.close() cmd_out = obj.stdout.read()
obj.stdout.close()
cmd_error = obj.stderr.read()
obj.stderr.close() print(cmd_out)
print(cmd_error)
import subprocess

obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
obj.stdin.write("print(1)\n")
obj.stdin.write("print(2)") out_error_list = obj.communicate()
print(out_error_list)
import subprocess

obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
out_error_list = obj.communicate('print("hello")')
print(out_error_list)

14:login模块

用于便捷记录日志且线程安全的模块

1、单文件日志

import logging

logging.basicConfig(filename='log.log',
format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S %p',
level=10) logging.debug('debug')
logging.info('info')
logging.warning('warning')
logging.error('error')
logging.critical('critical')
logging.log(10,'log')

日志等级:

CRITICAL = 50
FATAL = CRITICAL
ERROR = 40
WARNING = 30
WARN = WARNING
INFO = 20
DEBUG = 10
NOTSET = 0

注:只有【当前写等级】大于【日志等级】时,日志文件才被记录。

日志记录格式:

2、多文件日志

对于上述记录日志的功能,只能将日志记录在单文件中,如果想要设置多个日志文件,logging.basicConfig将无法完成,需要自定义文件和日志操作对象。

# 定义文件
file_1_1 = logging.FileHandler('l1_1.log', 'a', encoding='utf-8')
fmt = logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s")
file_1_1.setFormatter(fmt) file_1_2 = logging.FileHandler('l1_2.log', 'a', encoding='utf-8')
fmt = logging.Formatter()
file_1_2.setFormatter(fmt) # 定义日志
logger1 = logging.Logger('s1', level=logging.ERROR)
logger1.addHandler(file_1_1)
logger1.addHandler(file_1_2) # 写日志
logger1.critical('1111')
# 定义文件
file_2_1 = logging.FileHandler('l2_1.log', 'a')
fmt = logging.Formatter()
file_2_1.setFormatter(fmt) # 定义日志
logger2 = logging.Logger('s2', level=logging.INFO)
logger2.addHandler(file_2_1)

如上述创建的两个日志对象

  • 当使用【logger1】写日志时,会将相应的内容写入 l1_1.log 和 l1_2.log 文件中
  • 当使用【logger2】写日志时,会将相应的内容写入 l2_1.log 文件中

Python高手之路【七】python基础之模块的更多相关文章

  1. Python高手之路 ------读书有感

    最近忙中偷闲把前些年买的<Python高手之路>翻了出来,大致看完了一遍,其中很多内容并不理解,究其原因应该是实践中的经验不足,而这对于现如今的我仍是难以克服的事情,对此也就只能说是看会了 ...

  2. 《Python高手之路 第3版》这不是一本常规意义上Python的入门书!!

    <Python高手之路 第3版>|免费下载地址 作者简介  · · · · · · Julien Danjou 具有12年从业经验的自由软件黑客.拥有多个开源社区的不同身份:Debian开 ...

  3. python开发之路:python数据类型(老王版)

    python开发之路:python数据类型 你辞职当了某类似微博的社交网站的底层python开发主管,官还算高. 一次老板让你编写一个登陆的程序.咔嚓,编出来了.执行一看,我的妈,报错? 这次你又让媳 ...

  4. Python菜鸟之路:Python基础-模块

    什么是模块? 在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护.为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,分组的规则就是把实现了某个 ...

  5. Python高手之路【一】初识python

    Python简介 1:Python的创始人 Python (英国发音:/ˈpaɪθən/ 美国发音:/ˈpaɪθɑːn/), 是一种解释型.面向对象.动态数据类型的高级程序设计语言,由荷兰人Guido ...

  6. 我的Python成长之路---第六天---Python基础(18)---2016年2月20日(晴)

    os模块 提供对操作系统进行调用的接口 >>> import os >>> os.getcwd() # 获取当前工作目录,类似linux的pwd命令 '/data/ ...

  7. python学习之路-1 python简介及安装方法

    python简介 一种面向对象.解释型计算机程序设计语言,由Guido van Rossum于1989年发明,第一个公开发行版发行于1991年. 目前最新版本为3.5.1,发布于2015年12月07日 ...

  8. JVM菜鸟进阶高手之路十(基础知识开场白)

    转载请注明原创出处,谢谢! 最近没有什么实战,准备把JVM知识梳理一遍,先以开发人员的交流来谈谈jvm这块的知识以及重要性,依稀记得2.3年前用solr的时候老是经常oom,提到oom大家应该都不陌生 ...

  9. 【Python成长之路】Python爬虫 --requests库爬取网站乱码(\xe4\xb8\xb0\xe5\xa)的解决方法【华为云分享】

    [写在前面] 在用requests库对自己的CSDN个人博客(https://blog.csdn.net/yuzipeng)进行爬取时,发现乱码报错(\xe4\xb8\xb0\xe5\xaf\x8c\ ...

随机推荐

  1. linux后退文件夹命令

    后退文件夹: cd -  在重复一遍就是前进了

  2. 完整Highchart JS示例

    线性: $.ajax({ type:'post', url:appPages.urlListTjrll, cache:false, data:{year:year,month:month},// // ...

  3. TeamWork#3,Week5,Scrum Meeting 11.4

    今天我们进行了第一次Scrum Meeting,总结了最近一段时间的工作成果和经验教训,并分配了每个成员下一步的工作.网络爬虫对我们来说是一个难点,因为之前接触比较少,所以需要从头学起.我们参考了大量 ...

  4. [2017BUAA软工]结对项目:数独扩展

    结对项目:数独扩展 1. Github项目地址 https://github.com/Slontia/Sudoku2 2. PSP估计表格 3. 关于Information Hiding, Inter ...

  5. Beat(2/7)

    目录 摘要 团队部分 个人部分 摘要 队名:小白吃 组长博客:hjj 作业博客:beta冲刺(2/7) 团队部分 后敬甲(组长) 过去两天完成了哪些任务 整理博客 做了点商家数据表格 接下来的计划 做 ...

  6. 安装mysql后遇到的一些问题

    我们安装好了mysql(cnetos7上是安装mariadb)后,出现如下图所示的问题,我们可以用netstat -lntup查看以下服务器的端口,mysql的端口一般默认为 3306,查看服务是否启 ...

  7. Beta阶段DAY1

    一.提供当天站立式会议照片一张 二.每个人的工作 1.讨论项目每个成员的昨天进展 刘阳航:了解了自己再beta阶段的安排,但因为考试,有心无力. 林庭亦:颜色设置的相关代码的查看. 郑子熙:和另一位组 ...

  8. Openresty+Lua+Redis灰度发布

    灰度发布,简单来说,就是根据各种条件,让一部分用户使用旧版本,另一部分用户使用新版本.百度百科中解释:灰度发布是指在黑与白之间,能够平滑过渡的一种发布方式.AB test就是一种灰度发布方式,让一部分 ...

  9. 解决win10激活错误代码0xc004c003

    打开命令窗口(管理员). win10电脑图解-2 输入slmgr.vbs /upk,回车 激活错误电脑图解-3 输入:slmgr /ipk W269N-WFGWX-YVC9B-4J6C9-T83GX, ...

  10. Fastqc使用说明

    用FastQC检查二代测序原始数据的质量 2013-01-28 21:28:10|  分类: Bioinformatics |  标签:bioinformatics  deep-seq   |举报 | ...