? 导入
import test # test是模块名
test.func() # func() 是test模块中的函数调用
? 标准库,python解释器自带的.py文件(模块)
? 各种大神写的,需要额外下载的(并发编程开始讲解)(pypi)
? 自己写的,不需要额外下载
? 1.当前的名称空间中开辟一个新的空间(test)
? 2.将模块中所有的代码执行
? 3.通过模块名,进行查找函数(工具)
test模块
def func():
print("这是test文件下的func函数")
def foo():
print("这是test文件下的foo函数")
print(123)
print(456)
name = "这是名字"
import test
print(test.name)
print(test.func())
# 123
# 456
# 这是名字
# 这是test文件下的func函数
import test
import test
import test
import test
import test
import test
print(test.name)
# 123
# 456
# 这是名字
import test as t
print(t.name)
# 123
# 456
# 这是名字
test模块
def func():
print("扳手")
meet模块
def func():
print("螺丝刀")
msg = """
1.扳手
2.螺丝刀
"""
choose = input(msg)
if choose == "1":
import test as t
elif choose == "2":
import meet as t
t.func()
import test # 把工具箱拿过来 from test import func # 把工具拿过来
? 优点: 不会和当前文件定义的变量或者函数发生冲突
test模块
name = "alex"
import test
name = "宝元"
print(test.name)
print(name)
# alex
# 宝元
? 缺点: 占用内存比较大
? 优点: 占用内存比较小
? 缺点: 会和当前文件定义的变量或者函数发生冲突
test模块
name = "alex"
name = "宝元"
from test import name
print(name)
# alex 下面的变量或者函数会覆盖上面的
test模块
name = "alex"
name = "宝元"
from test import name as n
print(name)
pirnt(n)
# 宝元
# alex
test模块
name = "alex"
def func():
print("这是test下的func函数")
name = "宝元"
def func():
print("123")
from test import *
print(name)
func()
# alex
# 这是test下的func函数
# 注意会出现覆盖现象
? __all__ = ["要被导入的功能名字"]
test模块
name = "alex"
def func():
print("这是test下的func函数")
def foo():
print("这是test下的foo函数")
from test import foo
print(foo)
import test
print(test.foo)
? 1.脚本(在cmd中执行 python test.py)
? 2.模块(不使用或者导入)
if __name__ == "__main__"
在当前模块中使用__name__就是"__main__"
当模块被导入的时候__name__就是被导入的模块名
import meet
print(meet.name)
from day15.t1 import meet
print(meet.name)
from sys import path
path.insert(0,"D:\\")
import meet
print(meet.name)
? 自定义模块 > 内置模块 > 第三方
? time -- 时间(内置模块)
import time
时间戳
print(time.time())
# 时间戳 浮点数 可计算
print(time.time() + 5000)
睡眠
time.sleep(3)
# 睡眠 以秒为单位
时间节点
print(time.strftime("%Y-%m-%d %H:%M:%S"))
# 年-月-日 时:分:秒
# 2019-07-25 16:43:24
结构化时间
时间戳转结构化
print(time.gmtime()) / print(time.localtime())
# time.struct_time(tm_year=2019, tm_mon=7, tm_mday=25, tm_hour=8,
# tm_min=46, tm_sec=15, tm_wday=3, tm_yday=206, tm_isdst=0)
print(time.gmtime()[0]) / print(time.localtime()[0])
# 2019
print(time.gmtime().tm_year) / print(time.localtime().tm_year)
# 2019
字符串时间转结构化
print(time.strptime("2008-9-1 12:30:30","%Y-%m-%d %H:%M:%S"))
时间戳转换成字符串
print(time.strftime("%Y-%m-%d %H:%M:%S",time.gmtime(156156641.46854)))
# 1974-12-13 08:50:41
字符串转结构化转换成时间戳
print(time.mktime(time.strptime("2008-9-1 12:30:30","%Y-%m-%d %H:%M:%S")))
# 1220243430.0
? datetime -- 对象
from datetime import datetime
获取当前时间(浮点数)
print(datetime.now())
# 2019-07-25 17:24:58.037219
计算时间差距
print(datetime(2019,5,20,13,14,00) - datetime(2019,5,20,14,20,00))
# -1 day, 22:54:00
将当前时间转化成时间戳
print(datetime.now().timestamp())
# 1564047101.042584
将时间戳转化成当前时间
print(datetime.fromtimestamp(1564047101.042584))
# 2019-07-25 17:31:41.042584
将对象转成字符串
print(str(datetime.now()))
print(datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
# 2019-07-25 17:40:47
时间加减(datetime加减)
from datetime import datetime,timedelta
print(datetime.now() + timedelta(hours=30)) # 当前时间加30个小时
# 2019-07-27 00:19:38.461757
总结:
? 用处: 记录日志时使用
? 计算时间
? random -- 随机
import random
0-1随机取值(浮点数)
print(random.random())
# 0.04233141839466259
0-10随机取值(浮点数)
print(random.uniform(1,10))
# 1.0434503538907838
1-3随机取值(包含1和3)
print(random.randint(1,3))
# 1/2/3
randrange(起始,终止,步长)(顾头不顾尾)
print(random.randrange(1,5,2))
# 1/3
随机选择一个元素
print(random.choice([1,2,3,4,5]))
# 1/2/3/4/5
随机选择两个元素(会重复)
print(random.choices([1,2,3,4,5],k=2))
# 从列表中随机选择两个元素(会有重复元素,比如:[1,1])
随机选择两个元素(不会重复)
print(random.sample([1,2,3,4,5],k=2))
# 从列表中随机选择两个元素(不会有重复元素,除非列表只有两个重复元素,比如[1,1])
顺序打乱
lst = [1,2,3,4,5,6,7,8,9,0]
random.shuffle(lst)
print(lst)
# [4, 3, 9, 5, 1, 2, 8, 7, 6, 0]
# 随机打乱
import json
dumps 将对象转换成字符串(序列化)
lst = [1,2,3,4,5]
print(repr(json.dumps(lst)))
# "[1,2,3,4,5]"
loads 将字符串转换成对象(反序列化)
str_lst = ‘[1, 2, 3, 4, 5]‘
lst = json.loads(str_lst)
print(repr(lst))
# [1,2,3,4,5]
特例:
dic = {"k1":"名字"}
str_dic = json.dumps(dic)
print(str_dic)
# {"k1": "\u540d\u5b57"}
解决方法:
dic = {"k1":"名字"}
str_dic = json.dumps(dic,ensure_ascii=False)
print(str_dic)
# {"k1": "名字"}
# ensure_ascii=False 关闭ascii码
dump 将对象转换成字符串写入文件当中(序列化)
import json
lst = [1,2,3,4,5,6]
with open("info","w",encoding="utf-8")as f:
json.dump(lst,f)
# info文件中写入一行[1,2,3,4,5,6]
load 将文件中的字符串转换成对象(反序列化)
import json
lst = [1,2,3,4,5,6]
with open("info","r",encoding="utf-8")as f:
lst1 = json.load(f)
print(lst1)
# [1,2,3,4,5,6]
with open("info","r",encoding="utf-8")
for i in f:
l = json.loads(i)
print(l)
序列化(可对python所有对象进行转换)
python自带的(只有python可以用)
对象转换成类似字节
import pickle
lst = [1,2,3,4,5]
b_lst = pickle.dumps(lst)
print(b_lst)
# b‘\x80\x03]q\x00(K\x01K\x02K\x03K\x04K\x05e.‘
类似字节转换成对象
import pickle
lst = [1,2,3,4,5]
b_lst = pickle.dumps(lst)
t_lst = pickle.loads(b_lst)
print(t_lst)
# [1,2,3,4,5]
将对象转换成乱码写入对象
import pickle
dic = {"user":"baoyuan"}
pickle.dump(dic,open("info","wb"))
# ?}q X userqX baoyuanqs.
将乱码转换成对象输出
import pickle
dic = {"user":"baoyuan"}
pickle.dump(dic,open("info","wb"))
print(pickle.load(open("info","rb")))
# {‘user‘: ‘baoyuan‘}
import pickle
dic = {"1":2}
with open("info","wb")as f:
s = "\n".encode("utf-8")
f.write(pickle.dumps(dic) + s)
f.write(pickle.dumps(dic) + s)
f.write(pickle.dumps(dic) + s)
import pickle
dic = {"1":2}
with open("info","wb")as f:
s = "\n".encode("utf-8")
f.write(pickle.dumps(dic) + s)
f.write(pickle.dumps(dic) + s)
f.write(pickle.dumps(dic) + s)
f1 = open("info","rb")
for i in f1:
print(pickle.loads(i))
1.推荐使用json
2.json是各种语言通用的
3.pickle是python私有的
os模块 -- 程序员通过python向操作系统发送指令(与操作系统交互的接口)
当前工作路径 ***
print(os.getcwd())
路径切换 **
os.chdir(r"D:\pycharm demo\123")
当前目录
print(os.curdir)
父级目录
print(os.pardir)
import os
创建一个文件夹 ***
os.mkdir("ttt")
删除一个文件夹 ***
os.rmdir("ttt")
递归创建文件夹 ***
os.makedirs("ttt/sss/ddd/ee")
递归删除文件夹 ***
os.removedirs("ttt/sss/ddd/ee")
获取当前文件夹下所有文件名 ***
print(os.listdir())
import os
修改名字 ***
os.rename("123","info")
删除文件 ***
os.remove("info")
import os
通过相对路径获取绝对路径 ***
print(os.path.abspath("info"))
将路径以最后一个"\"切割(路径,文件名)
print(os.path.split(os.path.abspath("info")))
获取路径 ***
print(os.path.dirname("D:\pycharm demo\info"))
获取文件名 **
print(os.path.basename("D:\pycharm demo\info"))
判断路径是否存在 ***
print(os.path.exists("D:\pycharm demo\info"))
判断是不是路径 ***
print(os.path.isdir(r"D:\pycharm demo"))
判断是不是文件名 ***
print(os.path.isfile("info"))
判断是不是绝对路径 ***
print(os.path.isabs("D:\pycharm demo\info"))
路径拼接 *****
print(os.path.join("D:\\","pycharm demo","info"))
文件最后修改的时间(返回时间戳)
print(os.path.getatime("D:\pycharm demo\info"))
文件最后的访问时间(返回时间戳)
print(os.path.getctime("D:\pycharm demo\info"))
print(os.path.getmtime("D:\pycharm demo\info"))
获取当前文件的大小(返回字节b) ***
print(os.path.getsize("D:\pycharm demo\代码练习.py"))
sys -- 与python解释器交互的接口
import sys
脚本本身,当前文件运行(返回一个绝对路径) ***
print(sys.argv)
退出程序,正常退出时exit(0),错误退出sys.exit(1)
print(sys.exit(n))
获取解释器版本
print(sys.version)
添加自定义模块查找路径
print(sys.path)
区分操作系统然后进行相关逻辑操作
print(sys.platform)
hashlib 加密和校验
alex:alex123
加密后:alex:23lw23jky321jh4gqyt1234gj8b7t
{"1234":23lw23jky321jh4gqyt1234gj8b7t}
md5,sha1,sha256,sha512
1.只要明文相同密文就是相同的
2.只要明文不相同密文就是不相同的
3.不能反逆(不能解密) -- md5中国人破解了
1.加密的内容
2.将要加密的内容转成字节
md5示例:
import hashlib
md5 = hashlib.md5()
md5.update("alex123".encode("utf-8"))
print(md5.hexdigest())
sha1示例:
import hashlib
sha1 = hashlib.sha1()
sha1.update("alex123".encode("utf-8"))
print(sha1.hexdigest())
最常用的是md5但是被中国人破解
平时加密的时候使用sha1
import hashlib
md5 = hashlib.md5("alex".encode("utf-8"))
md5.update("wusir".encode("utf-8"))
print(md5.hexdigest())
user = input("user")
pwd = input("pwd")
import hashlib
md5 = hashlib.md5(user.encode("utf-8"))
md5.update(pwd.encode("utf-8"))
print(md5.hexdigest())
import hashlib
ss = "baoyuanwusirtaibai"
s = "baoyuan"
s1 = "wusir"
s2 = "taibai"
md5 = hashlib.md5()
md5.update(ss.encode("utf-8"))
print(md5.hexdigest())
import hashlib
ss = "baoyuanwusirtaibai"
s = "baoyuan"
s1 = "wusir"
s2 = "taibai"
md5 = hashlib.md5()
md5.update(s.encode("utf-8"))
md5.update(s1.encode("utf-8"))
md5.update(s2.encode("utf-8"))
print(md5.hexdigest())
# 拼接加密 和 分解加密 的加密结果一样
# 生成可以使用名字来访问元素内容的tuple
from collections import namedtuple
point = namedtuple("tu",["a","b","c"]) # 第一个参数是元组的名字,第二参数是元组中元素的[名字,名字]
p = point({"key":(1,2,3,4)},20,10)
print(p)
# tu(a={‘key‘: (1, 2, 3, 4)}, b=20, c=10)
# 双端队列,可以快速的从另外一端追加和推出对象
from collections import deque
lst = deque([1,2,3,4,5,6])
lst.append(8)
lst.appendleft(0)
print(lst)
# deque([0,1,2,3,4,5,6,8])
lst = deque([1,2,3,4,5,6])
lst.pop()
lst.popleft()
print(lst)
# deque([2,3,4,5])
# 队列:先进先出
# 栈:先进后出 -- 栈顶
c = Counter(‘abcdeabcdabcaba‘)
print(c)
# Counter({‘a‘: 5, ‘b‘: 4, ‘c‘: 3, ‘d‘: 2, ‘e‘: 1})
有序字典,python3.6以上默认有序
from collections import defaultdict
dic = defaultdict(list)
dic["k1"].append(12)
print(dic)
# defaultdict(<class ‘list‘>, {‘k1‘: [12]})
import re
s = "meet_宝元_meet"
print(re.findall("meet",s))
# [‘meet‘, ‘meet‘]
# 从字符串中全部查找内容,返回一个列表
s = "meet_宝元_meet123"
print(re.findall("\w",s))
# [‘m‘, ‘e‘, ‘e‘, ‘t‘, ‘_‘, ‘宝‘, ‘元‘, ‘_‘, ‘m‘, ‘e‘, ‘e‘, ‘t‘, ‘1‘, ‘2‘, ‘3‘]
# 查找数字,字母(中文),下划线
s = "meet_宝元_meet123!@#"
print(re.findall("\W",s))
# [‘!‘, ‘@‘, ‘#‘]
# 查找非数字,字母(中文),下划线
s = "meet_ 宝元_ me et\t \n"
print(re.findall("\s",s))
# [‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘, ‘\t‘, ‘ ‘, ‘\n‘]
# 查找任意空格,换行符,制表符
s = "meet_ 宝元_ me et\t \n"
print(re.findall("\S",s))
# [‘m‘, ‘e‘, ‘e‘, ‘t‘, ‘_‘, ‘宝‘, ‘元‘, ‘_‘, ‘m‘, ‘e‘, ‘e‘, ‘t‘]
# 查找非任意空格,换行符,制表符
s = "meet_ 宝元_123me et\t \n"
print(re.findall("\d",s))
# [‘1‘, ‘2‘, ‘3‘]
# 查找数字
s = "meet_ 宝元_123me et\t \n"
print(re.findall("\D",s))
# [‘m‘, ‘e‘, ‘e‘, ‘t‘, ‘_‘, ‘ ‘, ‘宝‘, ‘元‘, ‘_‘, ‘m‘, ‘e‘, ‘ ‘, ‘ ‘, ‘e‘, ‘t‘, ‘\t‘, ‘ ‘, ‘\n‘]
# 查找非数字
s = "meet宝元_123meet\t \n"
print(re.findall("\Ameet",s))
# [‘meet‘]
# 查找是否以什么开头
s = "meet宝元_123meet"
print(re.findall("meet\Z",s))
# [‘meet‘]
# 查找是否以什么结尾
s = "meet宝元_123meet \n \t \n"
print(re.findall("\n",s))
# [‘\n‘, ‘\n‘]
# 查找换行符
s = "meet宝元_123meet \n \t \n"
print(re.findall("\t",s))
# [‘\t‘]
# 查找制表符
s = "mtet宝元_123maet \n \t"
print(re.findall("m.e",s))
# [‘mte‘, ‘mae‘]
# .只能匹配任意一个内容(非换行符)
s = "m\net宝元_123maet \n \t "
print(re.findall("m.e",s,re.DOTALL))
# [‘m\ne‘, ‘mae‘]
# .只能匹配任意一个内容
s = "meet宝元_1A-23maet"
print(re.findall("[a-z]",s))
# [‘m‘, ‘e‘, ‘e‘, ‘t‘, ‘m‘, ‘a‘, ‘e‘, ‘t‘]
# 小写的a到z
print(re.findall("[A-Z]",s))
# [‘A‘]
# 大写的A到Z
print(re.findall("[A-Za-z]",s))
# [‘m‘, ‘e‘, ‘e‘, ‘t‘, ‘A‘, ‘m‘, ‘a‘, ‘e‘, ‘t‘]
# 大写和小写的A到Z,a到z
print(re.findall("[a-z0-9]",s))
# [‘m‘, ‘e‘, ‘e‘, ‘t‘, ‘1‘, ‘2‘, ‘3‘, ‘m‘, ‘a‘, ‘e‘, ‘t‘]
# 小写的a到z和数字0到9
s = "meet宝元_1A-23maet"
print(re.findall("[^0-9]",s))
# [‘m‘, ‘e‘, ‘e‘, ‘t‘, ‘宝‘, ‘元‘, ‘_‘, ‘A‘, ‘-‘, ‘m‘, ‘a‘, ‘e‘, ‘t‘]
# [^0-9] 查找非0-9的内容
s = "mmmmmm"
print(re.findall("m*",s))
# [‘mmmmmm‘, ‘‘]
# 匹配 * 前元素0个或多个 [贪婪匹配]
s = "meet_asdf_meees_mmns_aaam_meeeee"
print(re.findall("me+",s))
# [‘mee‘, ‘meee‘, ‘meeeee‘]
# 匹配 + 前元素一个或多个
s = "meet_asdf_m"
print(re.findall("m?",s))
# [‘m‘, ‘‘, ‘‘, ‘‘, ‘‘, ‘‘, ‘‘, ‘‘, ‘‘, ‘‘, ‘m‘, ‘‘]
# 匹配 ? 前元素0个或一个[非贪婪匹配]
s = "meet_asdf_msss_mmns_aaam"
print(re.findall("s{3}",s))
# [‘sss‘]
# 匹配 s{3} s重复3次 == sss
s = "meet_assdf_msss_mmns_aaam"
print(re.findall("s{1,3}",s))
# [‘ss‘, ‘sss‘, ‘s‘]
# 指定元素最少重复多少次,最多重复多少次
s = "meet_assdf_msss_mmns_aaam"
print(re.findall("m|s",s))
# [‘m‘, ‘s‘, ‘s‘, ‘m‘, ‘s‘, ‘s‘, ‘s‘, ‘m‘, ‘m‘, ‘s‘, ‘m‘]
# m|s,m或者s
s = "meet_meet_assdf_mssst_(.)mmns_aaamt"
print(re.findall("m(.+)t",s))
# [‘eet_meet_assdf_mssst_(.)mmns_aaam‘]
# m()t,取m与t中间的所有元素 [贪婪匹配]
s = "meet_assdf_mssst_(.)mmns_aaamaaat"
print(re.findall("m(?:..?)t",s))
# ["meet"]
# ?: 会匹配到括号两边的元素
扩展练习:
import re
s = "alex_sb ale123_sb wu12sir_sb wusir_sb ritian_sb 的 alex wusir "
print(re.findall("\w+_sb",s))
print(re.findall("[a-z]+_sb",s))
# [‘alex_sb‘, ‘ale123_sb‘, ‘wu12sir_sb‘, ‘wusir_sb‘, ‘ritian_sb‘]
# [‘alex_sb‘, ‘sir_sb‘, ‘wusir_sb‘, ‘ritian_sb‘]
print(re.findall("常(.*)娃","常鑫垃圾_井盖_烧饼吃娃娃_自行车_葫芦爷爷救娃娃"))
print(re.findall("常(.*?)娃","常鑫垃圾_井盖_烧饼吃娃娃_自行车_葫芦爷爷救娃娃"))
# [‘鑫垃圾_井盖_烧饼吃‘]
# [‘鑫垃圾_井盖_烧饼吃娃娃_自行车_葫芦爷爷救娃‘]
import re
s = "_sb alex 123_sb wu12sir_sb wusir_sb ritian_sb 的 x wusir "
print(re.search("ale",s).group())
# "ale"
# 找到一个元素后就停止查找,从字符串中进行查找,找到后返回的是一个元素,查看元素加.group()
# 如果字符串中没有该元素,报错
import re
s = ‘alex_sb alex 123_sb wu12sir_sb wusir_sb ritian_sb 的 x wusir ‘
print(re.match("ale",s).group())
# "ale"
# match 找到1个后就停止查找了,只从字符串的开头查找.找到后返回的是一个对象,查看元素.group()
# 如果字符串开头没有则报错
import re
s = "_sb alex,123:sb;wu12sir#sb*wusir!sb ritian_sb 的 x wusir "
print(re.split("[#,:!*]",s))
# [‘_sb alex‘, ‘123‘, ‘sb;wu12sir‘, ‘sb‘, ‘wusir‘, ‘sb ritian_sb 的 x wusir ‘]
# 分割
import re
print(re.sub("barry","太亮","barry是最好的讲师,barry就是一个普通老师,请不要将barry当男神对待"))
# 太亮是最好的讲师,太亮就是一个普通老师,请不要将太亮当男神对待
# 替换
obj = re.compile("\w")
print(obj.findall("meet_宝元_常鑫垃圾"))
# [‘m‘, ‘e‘, ‘e‘, ‘t‘, ‘_‘, ‘宝‘, ‘元‘, ‘_‘, ‘常‘, ‘鑫‘, ‘垃‘, ‘圾‘]
# 自定义匹配规则
g = re.finditer("\w","常鑫垃圾")
for i in g:
print(i.group())
# 常 鑫 垃 圾
# 返回的是一个迭代器的地址,查看元素加 .group()
import re
ret = re.search("<(?P<tag_name>\w+)>\w+</\w+>","<h1>hello</h1>")
print(ret.group("tag_name"))
print(ret.group())
# h1
# <h1>hello</h1>
import re
ret = re.search(r"<(\w+)>\w+</\1>","<h1>hello</h1>")
print(ret.group(1))
print(ret.group())
# h1
# <h1>hello</h1>
import re
ret = re.search("(?P<aaa>\w+)dfa","asbsadfasdfa")
print(ret.group())
print(ret.group("aaa"))
# asbsadfasdfa
# asbsadfas
? 文件夹下具有__init__.py文件的就是包
import 包.包.包
或者
from 包.包.包 import 模块
? 绝对路径:从最外层的包开始导入
? 相对路径:从当前(.)开始导入或者从父级(..)开始导入
? 使用相对路径的时候必须在包的外层且同级
? 需要在__init__.py文件中操作
python2: import 文件夹(没有__init__.py)报错
python3: import 文件夹(没有__init__.py)不报错
? logging -- 日志
? 记住怎么使用就好
# 自己定义日志开始
import logging.config
# 定义三种日志输出格式 开始
standard_format = ‘[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d][%(levelname)s][%(message)s]‘ #其中name为getlogger指定的名字
simple_format = ‘在 %(asctime)s %(message)s‘
id_simple_format = ‘[%(levelname)s][%(asctime)s] %(message)s‘
# log文件的全路径
logfile_path = ‘all2.log‘
# log配置字典
LOGGING_DIC = {
‘version‘: 1,
‘disable_existing_loggers‘: False,
‘formatters‘: {
‘standard‘: {
‘format‘: standard_format
},
‘simple‘: {
‘format‘: simple_format
},
},
‘filters‘: {},
‘handlers‘: {
#打印到终端的日志
‘stream‘: {
‘level‘: ‘DEBUG‘,
‘class‘: ‘logging.StreamHandler‘, # 打印到屏幕
‘formatter‘: ‘simple‘
},
#打印到文件的日志,收集info及以上的日志
‘file‘: {
‘level‘: ‘DEBUG‘,
‘class‘: ‘logging.handlers.RotatingFileHandler‘, # 保存到文件
‘formatter‘: ‘standard‘,
‘filename‘: None, # 日志文件
‘maxBytes‘: 1024*1024*1024, # 日志大小 5M
‘backupCount‘: 5,
‘encoding‘: ‘utf-8‘, # 日志文件的编码,再也不用担心中文log乱码了
},
},
‘loggers‘: {
#logging.getLogger(__name__)拿到的logger配置
‘‘: {
‘handlers‘: [‘stream‘, ‘file‘], # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
‘level‘: ‘DEBUG‘,
‘propagate‘: True, # 向上(更高level的logger)传递
},
},
}
def get_logger():
path = r‘F:\s24\day21\liye.log‘
LOGGING_DIC[‘handlers‘][‘file‘][‘filename‘] = path
logging.config.dictConfig(LOGGING_DIC) # 导入上面定义的logging配置
logger = logging.getLogger(__name__) # 生成一个log实例
return logger
def save():
logger = get_logger()
logger.info(f‘{} 存入300元‘) # 记录该文件的运行状态
save()
原文:https://www.cnblogs.com/liurui12138/p/14444079.html
异常处理
错误分类
语法错误
if 2 > 1 print(222) # 未加冒号 dic = {"name"; "alex"} # 字典中用冒号分隔键和值 tu = (2,3,4!5) # 元组中用逗号相隔
逻辑错误
num = int(input("请输入数字")) # 输入数字以外的内容,无法整型化,报错 dic = {"name": "海狗", "age": 18} dic["hobby"] # dic字典中没有["hobby"], 找不到报错
try except
try: num = int(input(‘>>>‘)) print(111) except ValueError: print(666) # input输入字符串类型的数字时, 输出111 # input输入字符串类型的非数字时, 输出666 try: dic = {‘name‘: ‘嘉欣‘} print(dic[‘age‘]) # 出现KeyError时 直接跳转except num = int(input(‘>>>‘)) print(111) except KeyError: print(555)
结构分类
结构1 单分支
try: num = int(input(">>>")) # 出现ValueError错误时, 直接跳转except dic = {"name": "嘉欣"} print(dic["age"]) print(111) except ValueError: print(666)
结构2 多分支
try: num = int(input(">>>")) dic = {"name": "嘉欣"} print(dic[‘age‘]) l1 = [1,2] print(l1[100]) print(111) except ValueError: print("输入的有非数字元素") except KeyError: print("没有此键") except IndexError: print("没有此下标") print(666)
结构3 万能异常处理 处理所有python可以识别的异常
try: dic = {"name": "嘉欣"} print(dic["age"]) l1 = [1,2] print(l1[100]) print(111) for i in 123: pass except Exception: print(666) # 有异常直接跳转except try: dic = {"name": "嘉欣"} # print(dic["age"]) l1 = [1,2] # print(l1[100]) print(111) for i in 123: pass except Exception as e: print(e) # 捕捉异常并打印出异常原因
tips
? 什么时候用万能? 什么时候用多分支?
? 如果你对错误信息不关心, 只是想排除信息继续让程序走下去, 用万能异常.
? 你对错误信息要进行明确的分流, 让你的程序多元化开发.
例如:
def func(): pass def func1(): pass dic = {1: func, 2: func1} try: num = int(input("请输入序号")) dic[num]() except ValueError: print("请输入数字") except KeyError: print("请输入范围内数字")
结构4 多分支 + 万能异常处理
def func(): pass def func1(): pass dic = {1: func, 2: func1} try: num = int(input("请输入序号")) dic[num]() except ValueError: print("请输入数字") except KeyError: print("请输入范围内数字") except Exception: print("程序出现了意料之外的错误...")
结构5 try else finally
try: dic = {"name": "嘉欣"} print(dic["age"]) l1 = [1, 2] print(l1[100]) print(111) except KeyError: print("没有此键") except IndexError: print("没有此下标") else: print("如果没有出现异常则执行这里") finally: print("finally 666") # except 必须依赖于try, else必须依赖于except和try # finally只是依赖于try # finally : 在异常出现之前, 执行finally try: dic = {"name": "嘉欣"} print(dic["age"]) l1 = [1,2] print(l1[100]) except KeyError: print("没有此键") except IndexError: print("没有此下标") except Exception: pass print(111) finally: print("finally 666") # finally 关闭数据库连接, 文件句柄关闭,数据保存等时,用到finally # 在return 结束函数之前, 执行finally代码 def func(): try: print(111) return 666 finally: print(222) print(func()) """ 111 222 666 """
结构6 主动触发异常
结构7 断言:展现出一种强硬的态度.
assert 条件 name = "alex" n1 = input("请输入:") assert name == n1 print(111) print(222)
结构8 自定义异常
# python 中给你提供的错误类型很多,但是不是全部的错误 class LiYeError(BaseException): def __init__(self, msg): self.msg = msg def __str__(self): return self.msg try: # 报错代码(万能异常处理无法识别) raise LiYeError("socket.connent...") except LiYeError as e: print(e)