1、上次内容回顾java
一、反射python
一、hasattr(对象,属性(字符串))c#
二、getattr(对象,属性(字符串))app
三、setattr(对象,属性,值)ide
四、delattr(对象,属性)函数
二、issubclass ,type , isinstancespa
issunclass,判断xxx对象或者类是不是xxx的子类debug
type:获取xxx对象的数据类型日志
isinstance:判断xxx对象是不是xxx类型(向上查找)code
三、方法和
类外面写的函数都是函数
在类中:
实例方法:
一、类名.方法() 函数
二、对象.方法() 方法
类方法:
都是方法
静态方法
都是函数
四、md5
特色:不可逆
加盐
import hashlib
obj = hashlib.md5(盐)
obj.update(byte类型的明文)
result = obj.hetdidest()
2、类的约束
类的约束,主要是为了定义一个父类,约束下面子类必须按照规则
完成父类中的功能(父类中的功能为空白)
在python中有两种办法来解决这样的问题
一、提取父类。而后再父类中定义好方法。在这个方法中什么都不用干,抛一个异常
就能够了。这样全部的子类都必须重写这个方法。不然,访问的时候报错
二、使用元类来描述父类。在元类中给出一个抽象方法。这样子类就不得不给出抽象方法
的具体实现。也能够起到约束的效果
第一套方案示例:
class Base: def login(self): raise Exception("你没有实现login⽅法()") class Normal(Base): def login(self): pass class Member(Base): def denglu(self): pass class Admin(Base): def login(self): pass # 项⽬经理写的总⼊⼝ def login(obj): print("准备验证码.......") obj.login() print("进⼊主⻚.......") n = Normal() m = Member() a = Admin() login(n) login(m) # 报错. login(a)
在执行到login(m)那一步程序报错,缘由是该类没有login方法,致使去
访问父类的login方法,抛出异常报错
Exception异常,是全部异常的根。咱们没法经过这个异常来判断出程序
是由于什么报的错。因此,最好是换一个比较专业的错误信息,换成NotlmplementError
意为:没实现的错误
第二套方案:写抽象类和抽象方法
from abc import ABCMeta, abstractmethod # 类中包含了抽象⽅法. 那此时这个类就是个抽象类. 注意: 抽象类能够有普通⽅法 class IGame(metaclass=ABCMeta): # ⼀个游戏到底怎么玩⼉? 你能形容? 流程能⼀样么? @abstractmethod def play(self): pass def turn_off(self): print("破B游戏不玩了, 脱坑了") class DNFGame(IGame): # ⼦类必须实现⽗类中的抽象⽅法. 不然⼦类也是抽象类 def play(self): print("dnf的玩⼉法") # g = IGame() # 抽象类不能建立对象 dg = DNFGame() dg.play() 经过代码咱们能发现. 这⾥的IGame对DNFGame进⾏了约束. 换句话说. ⽗类对⼦类进 ⾏了约束. 接下来. 继续解决咱们⼀开始的问题. from abc import ABCMeta, abstractmethod class Base(metaclass=ABCMeta): @abstractmethod def login(self): pass class Normal(Base): def login(self): pass class Member(Base): def denglu(self): # 这个就没⽤了 pass def login(self): # ⼦类对⽗类进⾏实现 pass class Admin(Base): def login(self): pass # 项⽬经理写的总⼊⼝ def login(obj): print("准备验证码.......") obj.login() print("进⼊主⻚.......") n = Normal() m = Member() a = Admin() login(n) login(m) login(a)
总结: 约束. 其实就是⽗类对⼦类进⾏约束. ⼦类必需要写xxx⽅法. 在python中约束的
⽅式和⽅法有两种:
1. 使⽤抽象类和抽象⽅法, 因为该⽅案来源是java和c#. 因此使⽤频率仍是不多的
2. 使⽤⼈为抛出异常的⽅案. 而且尽可能抛出的是NotImplementError. 这样比较专
业, ⽽且错误比较明确.(推荐)
3、异常处理
上来先制造个异常:
def chu(a, b): return a/b ret = chu(10, 0) print(ret) 结果: Traceback (most recent call last): File "/Users/sylar/PycharmProjects/oldboy/⾯向对象/day05.py", line 100, in <module> ret = chu(10, 0) File "/Users/sylar/PycharmProjects/oldboy/⾯向对象/day05.py", line 98, in chu return a/b ZeroDivisionError: division by zero 什么错误呢. 除法中除数不能是0. 那若是真的出了这个错. 你把这⼀堆信息抛给客户 么? 确定不能. 那如何处理呢? def chu(a, b): return a/b try: ret = chu(10, 0) print(ret) except Exception as e: print("除数不能是0") 结果: 除数不能是0
那try...except是什么意思呢? 尝试着运⾏xxxxx代码. 出现了错误. 就执⾏except后⾯的
代码. 在这个过程当中. 当代码出现错误的时候. 系统会产⽣⼀个异常对象. 而后这个异常会向
外抛. 被except拦截. 并把接收到的异常对象赋值给e. 那这⾥的e就是异常对象. 那这⾥的
Exception是什么? Exception是全部异常的基类, 也就是异常的跟. 换句话说. 全部的错误都
是Exception的⼦类对象. 咱们看到的ZeroDivisionError 其实就是Exception的⼦类. 那这样
写好像有点⼉问题撒. Exception表示全部的错误. 太笼统了. 全部的错误都会被认为是Exception.
当程序中出现多种错误的时候, 就很差分类了, 最好是出什么异常就⽤什么来处理. 这样就更加合理了.
因此在try...execpt语句中. 还能够写更多的except
import traceback # 计算a+b def cul(a, b): if (type(a) == int or type(a) == float) and (type(b) == int or type(b) == float): return a + b else: # 在这里有两种方案. 1. 直接返回 , 2. 抛出异常 # raise 抛出 Exception 错误和异常,全部错误的根 raise Exception("我要的不是这个. 你应该我传递int或者float") try: print(cul(1, "胡辣汤")) # 加上异常的处理 except Exception as e: # 获取到错误信息. 咱们须要访问堆栈信息 print(traceback.format_exc()) # 获取堆栈信息 print("出现了错误") 咱们出现的错误. python中没有给出具体的记录, 慎用. 名字必定要符合规范 JackException 一个让人无从得知的自定义异常,切记慎用自定义异常 自定义异常 class GenderException(Exception): pass class Person: def __init__(self, name, gender): self.name = name self.gender = gender # 洗澡 -> 男的进男浴室 def goto_nan_yushi(self): if self.gender != "男": raise GenderException("性别不对") # 除了名字之外都是父类中的Exception else: print("欢迎光临.") try: p2 = Person("wusir", "女") p2.goto_nan_yushi() p1 = Person("alex", "男") p1.goto_nan_yushi() except GenderException as e: print("你去男澡堂子干吗?") except Exception as e: print("其余错误")
4、日志处理
import logging # filename: ⽂件名 # format: 数据的格式化输出. 最终在⽇志⽂件中的样⼦ # 时间-名称-级别-模块: 错误信息 # datefmt: 时间的格式 # level: 错误的级别权重, 当错误的级别权重⼤于等于leval的时候才会写⼊⽂件 logging.basicConfig(filename='x1.log', format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S', level=30) # 当前配置表示 0以上的分数会被写⼊⽂件 # CRITICAL = 50 # FATAL = CRITICAL # ERROR = 40 # WARNING = 30 # WARN = WARNING # INFO = 20 # DEBUG = 10 # NOTSET = 0 logging.critical("我是critical") # 50分. 最贵的 logging.error("我是error") # 40分 logging.warning("我是warning") logging.info("我是info") logging.debug("我是debug") logging.log(1, "我什么都不是") import traceback try: print(1/0) except Exception: logging.error(traceback.format_exc()) # 用法 print("出错了") import logging # 建立⼀个操做⽇志的对象logger(依赖FileHandler) # open() file_handler = logging.FileHandler('zuo.log', 'a', encoding='utf-8') file_handler.setFormatter(logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s")) logger1 = logging.Logger('qq', level=20) logger1.addHandler(file_handler) # 把文件助手和日志对象绑定 logger1.error('我是A系统出错了') # 记录日志 # 再建立⼀个操做⽇志的对象logger(依赖FileHandler) file_handler2 = logging.FileHandler('you.log', 'a', encoding='utf-8') file_handler2.setFormatter(logging.Formatter(fmt="%(asctime)s - %(name)s -%(levelname)s -%(module)s: %(message)s")) logger2 = logging.Logger('B系统', level=20) logger2.addHandler(file_handler2) import traceback try: print(1/0) except Exception: logger2.critical(traceback.format_exc()) print("出错了. 请联系管理员") print("程序继续知悉个") from types import MethodType, FunctionType class Foo: @classmethod def func1(self): pass @staticmethod def func2(self): pass def func3(self): pass def func4(self): pass obj = Foo() lst.append(obj.func4) for item in lst: print(isinstance(item, MethodType))