约束、自定义异常、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 ...
随机推荐
- CoffeeScript 学习笔记
1.什么叫 CoffeeScript CoffeeScript 是一种新的编程语言,构建于 JavaScript 之上.CoffeeScript 提供了一种简洁的语法,对 Python 或 Ruby ...
- vue 跨域:使用vue-cli 配置 proxyTable 实现跨域问题
路径在/config/index.js 中,找到dev.proxyTable.如下配置示例: proxyTable: { '/api': { // 我要请求的地址 target: 'http://oa ...
- Atitit.跨语言数据库db api兼容性 jdbc odbc ado oledb 增强方案
Atitit.跨语言数据库db api兼容性 jdbc odbc ado oledb 增强方案 1. 跨语言db api兼容性..1 2. 目前访问数据库的接口很多.比较常用的jdbc odbc 以 ...
- 实时竞价(RTB) 介绍(基础篇)
前言: 说到"实时竞价"大家一定都不陌生,那么为何如今实时竞价发展这么迅猛,当然这个主要得益于总体移动互联网环境的成熟,以及中国本地移动广告市场出现爆发式增长.那么到底什么是实时竞 ...
- Flex colorTranfrom使用说明
这次使用colorTranfrom主要用来将一个已有的过渡颜色映射到其他颜色条.发现这个colorTranfrom很好使用,于是简单研究了下 文档有说明: 使用 ColorTransform 类调整显 ...
- 141. Sqrt(x) 【easy】
141. Sqrt(x) [easy] Implement int sqrt(int x). Compute and return the square root of x. Example sqrt ...
- ffffff
http://www.ibm.com/developerworks/cn/linux/l-cn-linuxglb/ http://blog.csdn.net/wocjj/article/details ...
- 深入浅出--iOS的TCP/IP协议族剖析&&Socket
深入浅出--iOS的TCP/IP协议族剖析&&Socket 简介 该篇文章主要回顾--TCP/IP协议族中的TCP/UDP.HTTP:还有Socket.(--该文很干,酝酿了许久! ...
- Flex读取txt文件里的内容报错
Flex读取txt文件里的内容 1.详细错误例如以下 2.错误原因 读取文件不存在 var file:File = new File(File.applicationDirectory.nativeP ...
- MapReduce源码分析之作业Job状态机解析(一)简介与正常流程浅析
作业Job状态机维护了MapReduce作业的整个生命周期,即从提交到运行结束的整个过程.Job状态机被封装在JobImpl中,其主要包括14种状态和19种导致状态发生的事件. 作业Job的全部状态维 ...