day26_异常_日志
内容回顾:
1. 成员
- 变量
- 静态字段,类变量
- 方法
- 类方法
- 静态方法
- 实例方法
- 属性
2. 对象的嵌套
3. 特殊方法
__init__
new
call
getitem...
add
enter
exit
iter
str
dict
doc
4. 反射
- getattr
- has
- set
- del
5. issubclass/isinstance/type/callable ——> 内置函数
6. 公有和私有(修饰符)
7. 三大特性:继承、封装、多态
8. super
9. 函数和方法的区别?
10. self到底是谁?
11. 继承、多继承
12. 关于类变量的改变
面向对象
- 三大特性
- 继承
- 单继承,示例:
- 多继承,示例:
- super
- 封装
- 数据封装
- 方法封装
- 多态
- 鸭子模型
- 成员
- 变量
- 实例
- 类
- 方法
- 示例方法
- 类方法
- 静态方法
- 特殊方法
...
- 属性
- @property,分页
- 修饰符
- 私有
- 编写
- 派生类
- 公有
- 易错点
- self
内置函数:
- issubclass
- isinstance
- type
- callable
函数和方法的区别?
反射
问题:匿名函数是否可以在类中?可以
class Foo:
v = lambda self,x: x+1 #和下面相等
def v(self,x):
return x + 1
今日内容:
1. 约束
2. 自定义异常
3. hashlib
4. logging
内容详细:
1. 约束
建议使用:
class BaseMessage(object):
def send(self):
"""
必须继承BaseMessage,然后其中必须编写send方法。用于完成具体业务逻辑。
"""
raise NotImplementedError("send方法必须被重写.")
# raise Exception(".send() 必须被重写.")
BaseMessage(基类)类用于约束,约束其派生类:保证派生类中必须编写send方法,不然执行就会报错。
class BaseMessage(object):
def send(self):
"""
必须继承BaseMessage,然后其中必须编写send方法。用于完成具体业务逻辑。
"""
raise Exception()
class Msg(BaseMessage):
def send(self):
pass # 发送短信
def f1(self):
pass
def f2(self):
pass
def func(arg):
"""
报警通知的功能
"""
arg.send()
obj = Msg()
func(obj)
Python:
类
类:
class Foo:
pass
抽象类和抽象方法:
from abc import ABCMeta,abstractmethod
class Base(metaclass=ABCMeta): # 抽象类;就是定义抽象方法
def f1(self):
print(123)
@abstractmethod #定义抽象方法;继承类的类必须重写此方法
def f2(self): # 抽象方法
pass
class Foo(Base):
def f2(self):
print(666)
obj = Foo()
obj.f1()
Java、C#中:
类
类
class Foo:
def f1(self):
pass
def f2(self):
pass # 可人为抛出异常让子类实现这个方法。
class Bar(Foo):
def f1(self):
pass
抽象类,约束,约束继承它的派生类必须实现它其中的抽象方法。;
abstact class Foo:
def f1(self):
print(1,3,4)
abstact def f2(self):pass
class Bar(Foo):
def f2(self):
print('111')
------------------------------------------------
接口,接口中不允许在方法内部写代码,只能约束继承它的类必须实现接口中定义的所有方法。
interface IFoo:
def f1(self,x1):pass
def f2(self,x1):pass
interface IBar:
def f3(self,x1):pass
def f4(self,x1):pass
class Foo(IFoo,IBar):# 实现了2个接口
def f1(self,x1):pass
def f2(self,x1):pass
def f3(self,x1):pass
def f4(self,x1):pass
总结:
1. 什么是接口以及作用?
接口时一种数据类型,主要用于约束派生类中必须实现指定的方法。
Python中不存在,Java和C# 中是存在的。
2. Python中使用过什么来约束呢?(两种方法如下)
1 - 抽象类+抽象方法, 这个编写上麻烦。
2 - 人为主动抛出异常 raise NotImplementedError('必须被重写')
3. 约束时,抛出的异常是否可以用其他的?
不专业:raise Exception(".send() 必须被重写.")
专业:raise NotImplementedError(".send() 必须被重写.")
看代码,揣摩心思
5. 写代码:
class BaseMessage(object):
def send(self,x1):
"""
必须继承BaseMessage,然后其中必须编写send方法。用于完成具体业务逻辑。
"""
raise NotImplementedError(".send() 必须被重写.")
class Email(BaseMessage):
def send(self,x1):
"""
必须继承BaseMessage,然后其中必须编写send方法。用于完成具体业务逻辑。
"""
print('发送邮件')
obj = Email()
obj.send(1)
6. 应用场景:
多个类,内部都必须有某些方法时,需要使用基类+异常进行约束。
学员管理程序:
class IBase:
def login():
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(self):
def login(self):
pass
....
2. 自定义异常
# 知识点:如何自定义异常类?
class MyException(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)
3. 加密
关键词:撞库
加盐
4. 日志 logging
为什么要有日志?
给开发人员看,用于排查错误。
import logging
import traceback
logger=logging.basicConfig(filename='xxxxxxx.txt',
format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S',
level=30 #默认登记是30
)
logging.debug("x1")
logging.info("x2")
logging.warning("x3")
logging.error('x4')
logging.critical("x5")
#自定义级别
logging.log(31,'655555555555')
# CRITICAL = 50
# FATAL = CRITICAL
# ERROR = 40
# WARNING = 30
# WARN = WARNING
# INFO = 20
# DEBUG = 10
# NOTSET = 0
def func():
try:
a=1+a
except Exception as e:
#获取堆栈信息
print("ddddddddd", type(e))
print(str(e),type(e))
msg=traceback.format_exc() #获取到哪一行的日志报错;获取日志多一点
logging.critical(msg)
func()
自定义日志
import logging
#创建一个操作日志的对象logger(依赖FileHandler);可以再创建一个相同的日志对象logger,这样就可以将日志写入两个文件了
file_handler=logging.FileHandler('11.txt','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('33333333333333333')
总结:
1. 约束 ***
2. md5 *****
3. 自定义异常 ***
4. 日志处理 ****
作业
1 类变量和实例变量的区别?
在类设计中,经常遇到两种类型的变量:类变量和实例变量。
简单的说,类变量(class variable)被该类的所有实例可以共享的变量;如果某个实例修改了该变量,这种变化可以被其他实例看到。
实例变量(object variable, instance variable)属于实例私有;对实例变量的操作不会影响到其他实例对象
一个是在类中,一个是在构造方法中
2 super的作用?
按照继承顺序查找下一个
super 是按照当前类的基础往上找,如果是self,则是回到原点找方法继续往上找
3 isinstance 和type的区别并用代码举例说明?
type更精准
4 补全代码
def func(arg):
#判断arg是否可以被调用,如果可以则执行并打印其返回值,
#否则直接打印结果
#用 callable 方发判断下即可
pass
5 补全代码
from types import MethodType,FunctionType
def func(*args):
#计算args 中函数,方法,Foo类对象的个数,并返回给调用者; 用 type
meth_count=0
func_count=0
obj_count=0
for i in args:
if isinstance(i,MethodType)
meth_count+=1
elif isinstance(I,FunctionType)
func_count+=1
elfi type(i,Foo)
return meth_count,func_count,obj_count
10 背写 你所了解的所有特殊方法并附示例
11
12
13
类变量和实例变量
15 如何让一个对象可以被执行?即后面加()
有 __call__ 方法
16
total_course_list=[]
class Course():
def __init__(self, name, price, period):
self.name = name
self.price = price
self.period = period
class Student:
func_list=[{'text':"选课","name":"select_course"},
{'text': "选课", "name": "select_course"},
{'text': "删除", "name": "select_course"}
]
def __init__(self, name):
self.name = name
self.course = []
def select_course(self):
"""选择课程,已选择则不能再选"""
for i,item in enumerate(total_course_list,1):
print(i,item.name,item.price,item.period)
num=int(input("请选择要选择的课程"))
num=num-1
course_obj=total_course_list[num]
if course_obj not in self.course:
self.course.append(course_obj)
print("选课成功")
def show_selected_course(self):
"""查看自己所选课程"""
pass
def show_deleted_course(self):
"""删除已选课程"""
pass
def run():
"""主程序
1 根据course类创建10个课程
2 用户输入学生姓名,动态创建学生对象
3 查看所有课程
4 为学生选课
5 查看学生已选课程
6 删除已选课程
"""
for i in range( 1, 11 ):
obj = Course( 'xx-%s' % i, 90, 90 )
total_course_list.append(obj)
stu_name=input("请输入学生姓名")
stu=Student(stu_name)
for i,item in enumerate(stu.func_list,1):
print(i,item['text'])
while True:
num=int(input("请选择执行的功能序号"))
num=num-1
row=stu.func_list[num]
name=row["name"]
func=getattr(stu,name)
func()
if __name__ == '__main__':
run()
第
二
total_course_list=[]
class Course():
def __init__(self, name, price, period):
self.name = name
self.price = price
self.period = period
class Student:
func_list=[{'text':"选课","name":"select_course"},
{'text': "选课", "name": "select_course"},
{'text': "删除", "name": "select_course"}
]
def __init__(self, name):
self.name = name
self.course = []
def select_course(self):
"""选择课程,已选择则不能再选"""
for i,item in enumerate(total_course_list,1):
print(i,item.name,item.price,item.period)
num=int(input("请选择要选择的课程"))
num=num-1
course_obj=total_course_list[num]
if course_obj not in self.course:
self.course.append(course_obj)
print("选课成功")
def show_selected_course(self):
"""查看自己所选课程"""
pass
def show_deleted_course(self):
"""删除已选课程"""
pass
def run():
"""主程序
1 根据course类创建10个课程
2 用户输入学生姓名,动态创建学生对象
3 查看所有课程
4 为学生选课
5 查看学生已选课程
6 删除已选课程
"""
for i in range( 1, 11 ):
obj = Course( 'xx-%s' % i, 90, 90 )
total_course_list.append(obj)
stu_name=input("请输入学生姓名")
stu=Student(stu_name)
for i,item in enumerate(stu.func_list,1):
print(i,item['text'])
while True:
num=int(input("请选择执行的功能序号"))
num=num-1
row=stu.func_list[num]
name=row["name"]
func=getattr(stu,name)
func()
if __name__ == '__main__':
run()
——异常