• day29


    今日内容:

      异常处理

      元类介绍

      元类(通过元类中的__init__方法,改变实例化获得的类)

      元类(通过元类中的__call__方法,改变实例化获得的类实例化出来的对象)

    1、异常处理:

      什么是异常处理?

        异常:异常就是错误发出的信号,一旦程序出错就会产生一个异常,如果该异常应用程序不处理,那么异常就会被抛出来,程序也会随之终止。

        异常包含三部分:

          1、traceback异常的追踪信息

          2、异常的信息

          3、异常的类型

        异常分为两大类:

          语法异常:应该在程序执行前就被修改

          逻辑异常

      为何用异常处理?

        避免程序因异常而崩溃,所以应该在程序中处理异常,增强程序健壮性。

    ##############################################################################

    如何用异常处理:

    try:
    代码1
    代码2
    ...
    except IndexError:
    ...
    except: ...:
    ...
    else:#在程序没有出错的情况下执行else下面的代码
    ...
    finally:#不管程序有没有出错都执行finally下面的代码,一般finally下面的代码用来回收资源
    ...

    ##############################################################################

    #############################################################################

     raise:可以主动抛出异常,一般与自定义的类结合使用

    class zjnu:
    def __init__(self,name,age):
    self.__name = name
    self.__age = age

    def get_info(self):
    print(self.__name,self.__age)

    def set_info(self,name,age):
    if not isinstance(name,str):
    raise Mymistake('名字必须是字符串')#主动抛出异常
    if not isinstance(age,int):
    raise Mymistake('年龄必须是整型')#主动抛出异常
    self.__name = name
    self.__age = age



    class Mymistake(BaseException):#自定义的一个异常
    def __init__(self,msg):
    self.msg = msg
    def __str__(self):
    return 'SB'
    stu1 = zjnu('yxf',18)
    stu1.get_info()
    stu1.set_info('lay',19)
    stu1.get_info()

    ################################################################################

    #######################################################################

    assert:断言,将程序分为两个部分,可以判断上半部分获取的数据,如果不符合就直接抛出异常

    L1 = [1,2,3,5,4]
    assert len(L1) == 5 #用来判断上半段代码执行完后一些数据是否符合条件,不符合条件就没有必要执行下半段代码了
    print('good job')

    #######################################################################

    元类:

      什么是元类?

        源自python中的一句话,一切皆对象,而对象是通过类的实例化而获得的

    #################################################################################

    class zjnu:
    def __init__(self,name,age):
    self.name = name
    self.age = age

    def get_info(self):
    print(self.name,self.age)

    tea1 = zjnu('lay',19)
    # tea1 是zjnu类的实例化获得的,那么我们就可以认为在定义zjnu时,
    # zjnu这个类也是一个类,是通过 zjnu = ...(...)来实例化获得的。

    class Zjnu:
    def __init__(self,name,age):
    self.name = name
    self.age = age

    def get_info(self):
    print(self.name,self.age)

    tea1 = Zjnu('lay',19)
    print(type(tea1))
    print(type(Zjnu))
    # 通过type(zjnu)我们发现zjnu = 元类(...)这是一个内置的元类:type.

    # 调用关系:
    # 调用元类实例化 ====》 自定义的类
    # 调用自定义的类实例化 ====》 自定义的对象

    # class关键字自定义类的底层原理:四步
    # 第一步:拿到自定义类的类名Zjnu
    # 第二步:找到自定义类的基类object
    # 第三步:产生一个空的名称空间
    # 第四步:调用元类type实例化获得Zjnu这个自定义的类 (Zjnu = type(Zjnu,(object,),{....}))

    # 自定义类的三个重要组成部分
    # 1、自定义类的类名
    # 2、自定义类的基类们
    # 3、自定义类的名称空间

    #################################################################################

    不依赖于class来模拟实例化出一个类

    #################################################################################

    # 第一步:拿到自定义的类名
    class_name = 'Zjnu'
    # 第二步:找到自定义类的基类们
    class_class = (object,)
    # 第三步:创建类的名称空间
    class_dic = {}
    class_body = '''
    def __init__(self,name,age):
    self.name = name
    self.age = age

    def get_info(self):
    print(self.name,self.age)
    '''
    exec(class_body,{},class_dic)
    # 第四步:调用type类实例化获得我们自定义的类
    Zjnu = type(class_name,class_class,class_dic)
    print(Zjnu.__dict__)
    tea1 = Zjnu('yxf',18)
    tea1.get_info()


    # 自定义元类模板
    class Myclass(type):
    def __init__(self,class_name,class_class,class_dic):
    print(self)
    print(class_name)
    print(class_class)
    print(class_dic)

    class Zjnu(metaclass=Myclass):#Zjnu = Myclass('Zjnu',(object,),{...})
    school = 'zjnu'
    def __init__(self,name,age):
    self.name = name
    self.age = age

    class Myclass(type):
    def __init__(self,class_name,class_class,class_dic):
    print(self)
    if class_name.islower():
    raise NameError('类名必须为驼峰体')
    print(class_name)
    print(class_class)
    print(class_dic)

    class zjnu(metaclass=Myclass):#Zjnu = Myclass('Zjnu',(object,),{...})
    school = 'zjnu'
    def __init__(self,name,age):
    self.name = name
    self.age = age

    ###################################################################################

    利用原类来控制类的调用:

    ####################################################################################

    class Myclass(type):
    def __call__(self, *args, **kwargs):
    # 1、先产生一个空对象
    obj_stu1 = self.__new__(self)
    # # 2、执行__init__方法,完成对空对象的初始化
    self.__init__(obj_stu1,*args,**kwargs)
    # 3、返回对象
    return obj_stu1

    class Zjnu(metaclass=Myclass):#Zjnu = Myclass('Zjnu',(object,),{...})
    school = 'zjnu'
    def __init__(self,name,age):
    self.name = name
    self.age = age
    stu1 = Zjnu('yxf',18)
    print(stu1.__dict__)


    # 利用元类来控制调用并将实例化的对象改成隐藏了的属性
    class Myclass(type):
    def __call__(self, *args, **kwargs):
    # 1、先产生一个空对象
    obj_stu1 = self.__new__(self)
    # # 2、执行__init__方法,完成对空对象的初始化
    self.__init__(obj_stu1,*args,**kwargs)
    obj_stu1.__dict__ = {'_%s__%s'%(self.__name__,k):v for k,v in obj_stu1.__dict__.items()}
    # 3、返回对象
    return obj_stu1

    class Zjnu(metaclass=Myclass):#Zjnu = Myclass('Zjnu',(object,),{...})
    school = 'zjnu'
    def __init__(self,name,age):
    self.name = name
    self.age = age

    stu1 = Zjnu('yxf',18)
    print(stu1.__dict__)

    ###################################################################################

    关于__new__属性查找的顺序

    ################################################################################################################

    class Myclass(type):
    def __call__(self, *args, **kwargs):
    # 1、先产生一个空对象
    obj_stu1 = self.__new__(self) # 这个__new__依照属性查找mro的规则先从自己(Zjnu)开始依次查找,最终找到元类中的__new__方法
    # # 2、执行__init__方法,完成对空对象的初始化
    self.__init__(obj_stu1,*args,**kwargs)
    obj_stu1.__dict__ = {'_%s__%s'%(self.__name__,k):v for k,v in obj_stu1.__dict__.items()}
    # 3、返回对象
    return obj_stu1
    class Bar(object):
    # xxx = '333'
    def asd(self):
    pass

    class Foo(Bar):
    # xxx = '222'
    def arr(self):
    pass

    class Zjnu(Foo,metaclass=Myclass):#Zjnu = Myclass('Zjnu',(object,),{...})
    # xxx='111'
    school = 'zjnu'
    def __init__(self,name,age):
    self.name = name
    self.age = age

    stu1 = Zjnu('yxf',18)
    print(stu1.xxx)
  • 相关阅读:
    说说ReactiveCocoa 2
    xcode5 添加Build Phases脚本
    关于CoreData的一个工具Mogenerator的使用
    Keystone controller.py & routers.py代码解析
    Openstack Restful API 开发框架 Paste + PasteDeploy + Routes + WebOb
    Openstack Restful API 开发框架 Paste + PasteDeploy + Routes + WebOb
    Web 开发规范 — WSGI
    Web 开发规范 — WSGI
    Openstack API 类型 & REST 风格
    Openstack API 类型 & REST 风格
  • 原文地址:https://www.cnblogs.com/yaoxiaofeng/p/9544883.html
Copyright © 2020-2023  润新知