约束、自定义异常、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 ...
随机推荐
- C# JSON序列化日期格式问题
默认序列化日期为1970至今的时间戳 需要在json.convert中做一些设置 //JavaScriptSerializer js = new JavaScriptSerializer(); Iso ...
- struts2学习笔记(一)
1.搭建第一个struts2 app. web.xml <?xml version="1.0" encoding="UTF-8"?> <we ...
- 非常酷的 Javascript 简单调试工具Blackbird
Blackbird 是一个开源的 Javascript 调试工具,默认提供一种非常酷的方式展现 Javascript 调试信息,如下图,效果如何呢? 在我们的日常的学习或工作中,经常都会接触到 Jav ...
- MvcPager帮助文档 - MvcAjaxOptions 类
表示用于 MvcPager 在 Ajax 分页模式下的选项设置,该类继承自 AjaxOptions. 公共属性: 名称 说明 默认值 AllowCache 获取或设置一个值,该值指示是否在Ajax分页 ...
- Hive 正则匹配函数
正则匹配字符解释: ^ 表示开头 $ 表示结尾 . 表示任意字符 * 表示任意多个 regexp_extract函数 语法: regexp_extract(string subject, st ...
- 使用 %matplotlib inline 出错?
%matplotlib inline 是一个魔法函数(Magic Functions).官方给出的定义是:IPython有一组预先定义好的所谓的魔法函数(Magic Functions),你可以通过命 ...
- URAL 1750 Pakhom and the Gully 计算几何+floyd
题目链接:点击打开链接 gg.. . #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cs ...
- HDU高精度总结(java大数类)
HDU1002 A + B Problem II [题意]大数相加 [链接]http://acm.hdu.edu.cn/showproblem.php?pid=1002 Sample Inpu ...
- 创建一个视图JSP文件的helloWorld.jsp
让我们创建下面的JSP文件的helloWorld.jsp,在WebContent文件夹在你的eclipse项目.要做到这一点,右键单击WebContent文件夹中的项目资源管理器,然后选择“新建”&g ...
- python django -1
VT Django是一款python的web开发框架 与MVC有所不同,属于MVT框架 m表示model,负责与数据库交互 v表示view,是核心,负责接收请求.获取数据.返回结果 t表示templa ...