约束、自定义异常、hashlib模块、logging日志模块
一、约束(重要***)
1、首先我们来说一下java和c#中的一些知识,学过java的人应该知道,java中除了有类和对象之外,还有接口类型,java规定,接口中不允许在方法内部写代码,只能约束继承它的类必须实现接口中定义的所有方法,为了便于理解,我们用python和java混合语法来写一下java中的接口,如下示例:
interface IFoo: # 定义接口Ifoo,接口内部的方法不能写任何功能代码
def f1(self, x1):
pass
def f2(self, x1):
pass interface IBar: # 定义接口Ibar,接口内部的方法不能写任何功能代码
def f3(self, x1):
pass
def f4(self, x1):
pass class Foo(IFoo, IBar): # 实现了2个接口,不叫继承,java、c#不支持多继承
def f1(self, x1):
pass
def f2(self, x1):
pass
def f3(self, x1):
pass
def f4(self, x1):
pass
注意:java、c#是编译型语言,如果类Foo中没有实现其2个接口的所有方法,则无法编译
java和c#知识
除了接口以外,java中还有抽象方法、抽象类的概念:抽象类可以约束继承它的派生类必须实现它其中的抽象方法,如下示例:
abstract class Foo: # 定义一个抽象类
def f1(self):
print(1, 3, 4) # 定义抽象方法,用来约束,内部不能写功能代码
abstract def f2(self):
pass class Bar(Foo):
def f2(self):
print('')
# 抽象类Foo的派生类Bar必须实现Foo类中的抽象方法,否则无法编译
# 其他非抽象方法可以正常写功能代码以供派生类调用
java中的抽象方法、抽象类
综上可解决问题:什么是接口以及它的作用?
接口是一种数据类型,主要用于约束派生类中必须实现指定的方法,java和c#中存在。
2、介绍到这里你可能也在想python中有没有接口呢?答案是没有!那python使用什么来约束呢?如下:
# ### 示例一:python中的使用抽象方法、抽象类约束
from abc import ABCMeta,abstractmethod class Base(metaclass=ABCMeta): # 抽象类
def f1(self):
print(123) @abstractmethod
def f2(self): # 抽象方法,方法上方加@abstractmethod
pass class Foo(Base):
# Foo中必须重写父类Base中的抽象方法,否则程序无法执行
def f2(self):
print(666)
# ### 示例二:人为主动抛出异常来约束
class BaseMessage(object):
def send(self,x1):
"""
必须继承BaseMessage,然后其中必须编写send方法。用于完成具体业务逻辑。
"""
raise NotImplementedError(".send() 必须被重写.") class Email(BaseMessage):
def send(self,x1):
print('发送邮件') obj = Email()
obj.send(1)
总结:python中有两种方法来约束:
1)抽象类+抽象方法,编写上比较麻烦,不推荐;
2)人为主动抛出异常,源码也是这样写的,推荐;
注意:抛出异常也可以用raise Exception(),但是推荐使用raise NotImplementedError()。
3、约束的应用场景:有多个类,内部都必须有某些方法时,需要使用基类+异常进行约束。如下示例:
# ### 应用示例:学员管理系统
class IBase:
def login(self):
raise NotImplementedError(".send() 必须被重写.") class Student:
def login(self):
pass
def score(self):
pass class Teacher:
def login(self):
pass
def exam(self):
pass class Manager:
def login(self):
pass
def func(self):
pass
约束的应用场景
二、自定义异常(***)
以前的处理异常的写法,如下示例:
# ### 示例一:
import os
def func(path,prev):
"""
去path路径的文件中,找到前缀为prev的一行数据,获取数据并返回给调用者。
1000,成功
1001,文件不存在
1002,关键字为空
1003,未知错误
...
"""
response = {'code':1000,'data':None}
try:
if not os.path.exists(path):
response['code'] = 1001
response['data'] = '文件不存在'
return response
if not prev:
response['code'] = 1002
response['data'] = '关键字为空'
return response
pass # 这里是正常的业务逻辑代码
except Exception as e:
response['code'] = 1003
response['data'] = '未知错误'
return response
以前的写法
学完面向对象后,我们可以自定义异常,好处是try部分的功能代码逻辑更加清晰,如下示例:
# ### 示例二:自定义异常
import os class ExistsError(Exception):
pass class KeyInvalidError(Exception):
pass def new_func(path,prev):
"""
去path路径的文件中,找到前缀为prev的一行数据,获取数据并返回给调用者。
1000,成功
1001,文件不存在
1002,关键字为空
1003,未知错误
...
"""
response = {'code':1000,'data':None}
try:
if not os.path.exists(path):
raise ExistsError()
if not prev:
raise KeyInvalidError()
pass # 这里是正常的业务逻辑代码
except ExistsError as e:
response['code'] = 1001
response['data'] = '文件不存在'
except KeyInvalidError as e:
response['code'] = 1002
response['data'] = '关键字为空'
except Exception as e:
response['code'] = 1003
response['data'] = '未知错误'
return response
现在的写法
总结:自定义异常的知识点有三个,如下示例:
# 知识点:如何自定义异常类?
class MyException(Exception): # Exception是所有异常类的基类
def __init__(self, code, msg):
self.code = code
self.msg = msg
try:
raise MyException(1000, '操作异常') # 知识点:主动抛出异常
except KeyError as obj:
print(obj, 1111)
except MyException as obj: # 知识点:捕获自定义的异常
print(obj, 2222)
except Exception as obj:
print(obj, 3333)
三、hashlib模块(*****)
我们以后存密码时一定要存成密文,不能是明文,那如何把字符串加密成密文呢?python提供了一个模块hashlib,使我们可以对一个字符串进行加密。下面来学习一下,如下示例:
import hashlib
# 为了防止别人用撞库破解,我们可以再加盐处理
SALT = b'2erer3asdfwerxdf34sdfsdfs90'
def md5(pwd):
obj = hashlib.md5(SALT) # 实例化对象
# 写入要加密的字节,在python3中必须是字节,所以要将字符串转成字节
obj.update(pwd.encode('utf-8'))
v = obj.hexdigest() # 获取密文
return v user = input("请输入用户名:")
pwd = input("请输入密码:") # admin
# md5加密是不可逆的,无法解密,所以验证时要进行密文验证
if user == 'oldboy' and md5(pwd) == 'c5395258d82599e5f1bec3be1e4dea4a':
print('登录成功')
else:
print('登录失败')
四、logging日志模块(****)
先思考一个问题:为什么要有日志?日志是给开发人员看,用于排查错误。
1、python为我们提供了一个logging模块,它是一个用于便捷记录日志且线程安全的模块。
函数式的简单配置如下:
import logging
logging.debug('debug message') # level = 10
logging.info('info message') #
logging.warning('warning message') #
logging.error('error message') #
logging.critical('critical message') #
logging.log(60, '自定义的level')
# 结果为:
# WARNING:root:warning message
# ERROR:root:error message
# CRITICAL:root:critical message
# Level 60:root:自定义的level
默认情况python的logging模块将日志打印到了标准输出中,且只显示了大于等于warning级别的日志,这说明默认的日志级别level设置为warning(日志级别等级critical > error > warning > info > debug),默认的日志显示格式为:日志级别:logger名称:用户输出消息。
logging.basicConfig()函数中可通过具体参数来更改logging模块默认行为,可用的参数有:
filename:用指定的文件名创建FiledHandler,这样日志会被存储在指定的文件中;
format:指定handler使用的日志显示格式;
datefmt:指定日期时间格式;
level:设置rootlogger(后边会讲解具体概念)的日志级别;
filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”;
stream:用指定的stream创建StreamHandler。可以指定输出到 sys.stderr,sys.stdout或者文件(f=open(‘test.log’,’w’)),默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略;
具体参数
具体示例如下:
import logging logger = logging.basicConfig(filename='wllog.txt',
format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S',
level=20) logging.debug('debug message')
logging.info('info message')
logging.warning('warning message')
logging.error('error message')
logging.critical('critical message')
logging.log(60, '自定义的level')
2、获取当前错误的堆栈信息并写入日志,如下示例:
import logging logger = logging.basicConfig(filename='wllog.txt',
format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S',
level=30) import traceback def func():
try:
a = a +1
except Exception as e: # e其实是一个对象
# 获取当前错误的堆栈信息,有文件和错误所在行
msg = traceback.format_exc()
logging.error(msg)
# 只写入错误信息描述,没有发生错误文件和错误所在行
# logging.error(str(e))
func()
3、多文件日志
对于上述记录日志的功能,只能将日志记录在单文件中,如果想要设置多个日志文件,logging.basicConfig将无法完成,需要自定义文件和日志操作对象,如下示例:
# 创建一个操作日志的对象logger(依赖FileHandler)
file_handler = logging.FileHandler('l1.log', 'a', encoding='utf-8')
file_handler.setFormatter(logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s")) logger1 = logging.Logger('s1', level=logging.ERROR)
logger1.addHandler(file_handler) logger1.error('') # 再创建一个操作日志的对象logger(依赖FileHandler)
file_handler2 = logging.FileHandler('l2.log', 'a', encoding='utf-8')
file_handler2.setFormatter(logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s")) logger2 = logging.Logger('s2', level=logging.ERROR)
logger2.addHandler(file_handler2) logger2.error('')
日志
如上述创建的两个日志对象
当使用logger1写日志时,会将相应的内容写入l1.log文件中;
当使用logger2写日志时,会将相应的内容写入l2.log文件中;
约束、自定义异常、hashlib模块、logging日志模块的更多相关文章
- hashlib加密模块、logging日志模块
hashlib模块 加密:将明文数据通过一系列算法变成密文数据 目的: 就是为了数据的安全 基本使用 基本使用 import hashlib # 1.先确定算法类型(md5普遍使用) md5 = ha ...
- day31 logging 日志模块
# logging 日志模块 ****** # 记录用户行为或者代码执行过程 # print 来回注释比较麻烦的 # logging # 我能够“一键”控制 # 排错的时候需要打印很多细节来帮助我排错 ...
- Python入门之logging日志模块以及多进程日志
本篇文章主要对 python logging 的介绍加深理解.更主要是 讨论在多进程环境下如何使用logging 来输出日志, 如何安全地切分日志文件. 1. logging日志模块介绍 python ...
- 包,logging日志模块,copy深浅拷贝
一 包 package 包就是一个包含了 __init__.py文件的文件夹 包是模块的一种表现形式,包即模块 首次导入包: 先创建一个执行文件的名称空间 1.创建包下面的__init__.py文件的 ...
- logging 日志模块学习
logging 日志模块,用于记录系统在运行过程中的一些关键信息,以便于对系统的运行状况进行跟踪,所以还是灰常重要滴,下面我就来从入门到放弃的系统学习一下日志既可以在屏幕上显示,又可以在文件中体现. ...
- logging日志模块
为什么要做日志: 审计跟踪:但错误发生时,你需要清除知道该如何处理,通过对日志跟踪,你可以获取该错误发生的具体环境,你需要确切知道什么是什么引起该错误,什么对该错误不会造成影响. 跟踪应用的警告和错误 ...
- python 自动化之路 logging日志模块
logging 日志模块 http://python.usyiyi.cn/python_278/library/logging.html 中文官方http://blog.csdn.net/zyz511 ...
- logging日志模块的使用
logging日志模块的使用 logging模块中有5个日志级别: debug 10 info 20 warning 30 error 40 critical 50 通常使用日志模块,是用字典进行配置 ...
- Python 中 logging 日志模块在多进程环境下的使用
因为我的个人网站 restran.net 已经启用,博客园的内容已经不再更新.请访问我的个人网站获取这篇文章的最新内容,Python 中 logging 日志模块在多进程环境下的使用 使用 Pytho ...
随机推荐
- 神技do{}while(false)
神技do{}while(false) do{}while(false)或者说do{}while(0),本人在linux源码中学得,起初看起来比较奇怪,但在处理连续流程中特别有用,例如ABC三个流程,A ...
- WPF开源框架项目
好久博客未更新新博文了,今天介绍一个WPF开源框架MaterialDesignInXamlToolkit废话不多说先让我们来看看框架得几张截图 让我们一起来看看源代码得结构如下图 接下我们运行代码看看 ...
- Audio简介
本片只简单从硬件角度简介Audio AC97/HDA Audio总线分两种: (1)I2S (2)HDA HD Audio spec Audio verb table是用来初始化audio的,一个au ...
- Go环境IDE安装配置
终于配好了自己的Go环境,每天可以来一点积累了. MAC安装配置过程参考了如下几个博文~谢谢 Intellij安装配置: http://blog.csdn.net/fenglailea/article ...
- SourceTree代码管理学习git命令操作
Git管理工具SourceTree提交代码时报文件名过长,用命令解决这个错误: 使用git status查看状态信息 git status 使用git add将修改后的文件(.代表全部文件)添加到暂存 ...
- webpack 环境搭建基础框架
一.安装babel相关 1,安装依赖 cnpm i -D babel-core babel-loader babel-preset-env babel-preset-stage- babel-plug ...
- SDRAM驱动篇之简易SDRAM控制器的verilog代码实现
在Kevin写的上一篇博文<SDRAM理论篇之基础知识及操作时序>中,已经把SDRAM工作的基本原理和SDRAM初始化.读.写及自动刷新操作的时序讲清楚了,在这一片博文中,Kevin来根据 ...
- LNMP平滑升级nginx并安装ngx_lua模块教程
#ngx_lua module项目地址 https://github.com/chaoslawful/lua-nginx-module 在LNMP安装包后,重编译nginx,并添加ngx_lua模块 ...
- sql server 数据库基础知识(二)
CASE函数用法1:单值判断,相当于switch caseCASE expression WHEN value1 THEN returnvalue1 WHEN value2 THEN returnva ...
- FreeMarker中在list中加入if判断
例如list中遍历releaseitem,在ri中获取audit的值,如果audit的值为0则表示正在审核中,如果为1则表示审核通过,如果为2则表示未审核. <#list releaseitem ...