class B(object): # type("B",(object,),{"name":"rose"}) name = "rose"
class_text = """ class A: def test(self): print(self) """ loca2 = {} exec(class_text,None,loca2) print(loca2) # {'A':}
class MyMetaClass(type): def __init__(self,class_name,bases,name_dict): # 元类中的self表示的都是类对象 # 不要忘记调用父类的初始化 super().__init__(class_name,bases,name_dict) print(name_dict) # 类名必须首字母大写 否则直接抛出异常 if not class_name.istitle(): print("类名必须大写 傻x!") raise Exception # 控制类中方法名必须全部小写 for k in name_dict: if str(type(name_dict[k])) == "": if not k.islower(): print("方法名称必须全小写 傻蛋!") raise Exception pass # 会自动调用其元类中的 __init__ 方法传入 类对象本身 类名称 父类们 名称空间 class Student(object,metaclass=MyMetaClass): # MyMetaClass("Student",(object,),{}) NAME = 10 def say(self): print("SAY") pass
1.执行MyMetaClass的__new__
方法 拿到一个类对象
2.执行MyMetaClass的__init__
方法 传入类对象以及其他的属性 ,进行初始化
注意:如果覆盖了__new__
一定也要调用type中的__new__
并返回执行结果(如果不返回就无法执行init)
class MyMetaClass(type): def __init__(self,class_name,bases,name_dict): # super().__init__(class_name,bases,name_dict) print("init") pass # 该方法会在实例化类对象时自动调用并且在 init 之前调用 # 其作用时用于创建新的类对象的 # 注意这里必须调用type类中的__new__ 否则将无法产生类对象 并且返回其结果 def __new__(cls, *args, **kwargs): # cls 表示元类自己 即MyMetaClass # print("new") # print(args,kwargs) return type.__new__(cls,*args,**kwargs) # 如果覆盖__new__ 一定要写上这行代码 class Person(metaclass=MyMetaClass): pass
_new__ __init__ 是创建类对象时还会执行 # __call__ 类对象要产生实例时执行
class MyMeta(type): # 获得某个类的实例 def __call__(self, *args, **kwargs): print("call") # return super().__call__(*args,**kwargs) new_args = [] for i in args: if isinstance(i,str): new_args.append(i.upper()) else: new_args.append(i) return super().__call__(*new_args,**kwargs) # 注意注意注意: __new__ __init__ 是创建类对象时还会执行 # __call__ 类对象要产生实例时执行 class Student(metaclass=MyMeta): def __init__(self,name,gender,age): self.name = name self.gender = gender self.age = age s = Student("jack","woman",18) print(s.age) print(s.gender) class Person(metaclass=MyMeta): def __init__(self,name,gender): self.name = name self.gender = gender p = Person("rose","man") print(p.name)
元类的单例模式
1.什么是单例:某个类如果只有一个实例对象,那么该类成为单例类
2.为什么要用单例:避免资源浪费
3.例:
class SingletonMetaClass(type): # 创建类时会执init 在这为每个类设置一个obj属性 默认为None def __init__(self, a, b, c): super().__init__(a, b, c) self.obj = None # 当类要创建对象时会执行 该方法 def __call__(self, *args, **kwargs): # 判断这个类 如果已经有实例了就直接返回 从而实现单例 if self.obj: return self.obj # 没有则创建新的实例并保存到类中 obj = type.__call__(self, *args, **kwargs) self.obj = obj return obj
异常
1.什么是异常:程序运行过程中发生的非正常情况,是一个错误发生时的信号,
异常如果没有被正确处理的话,将导致程序被终止,这对于用户体验是非常差的,可能导致严重的后果
处理异常的目的就是提高程序的健壮性
运行时异常,已经通过语法检测,开始执行代码,执行过程中发生异常 称之为运行时异常
3.异常组成:
Traceback 是异常追踪信息 用于展示错误发生的具体位置 以及调用的过程
其中 包括了 错误发生的模块 文件路径 行号 函数名称 具体的代码最后一行 前面是错误的类型
后面 错误的详细信息 在查找错误时 主要参考的就是详细信息1.语法:
try:
可能会出现异常的代码 放到try里面
except 具体异常类型 as e:
如果真的发生异常就执行except
断言assert
断言 其实可以理解为断定的意思
即非常肯定某个条件是成立的
条件是否成立其实可以使用if来判断
其存在的目的就是 为了简化if 判断而生的