zoukankan      html  css  js  c++  java
  • python day 11: 类的补充,元类,魔法方法,异常处理

    python day 11

    2019/10/14

    学习资料来自老男孩与尚学堂

    1. 类的补充

    1.1 通过反射来查找类,创建对象,设置对象的属性与方法

    #通过__import__输入字符串文件名的方式导入模块
    m = __import__('getattr_setattr', fromlist=True)
    if hasattr(m, 'Foo'):
        # 去模块中找类
        Foo = getattr(m, 'Foo')
        # 根据类创建对象
        obj1 = Foo()
        # 通过对象找到对象的属性
        n1 = getattr(obj1, 'n1')
        # 通过反射找到对象的方法
        show = getattr(obj1, 'show')
        obj1.show()
        print(obj1.n1)
        # 通过反射设置对象的属性
        setattr(obj1, 'name', 'lanxing')
        print(obj1.name)
    
        # 通过反射设置对象的方法
        setattr(obj1, 'func1', lambda x: x + 1)
        # def func1(x):
        #     return x + 1
    
        # setattr(obj1, 'func1', func1)
        print(obj1.func1(2))
    

    1.2 类的魔法方法:getitem,setitem

    class Foo(object):
        def __init__(self, key):
            self.key = key
    
        def __call__(self, *args, **kwargs):  # __call__定义类的对象可以当作函数来调用
    
            return 1
    
        def __getitem__(self, key):  # obj['item'],obj[1:3]也是用的这种方法
            if self.key:
                return self.key
            else:
                return None
    
        def __setitem__(self, key, value):  # obj[key] = value
            self.key = value
    
        def __delitem__(self, key):  # del obj[key]
            pass
    
        def __iter__(self):  # for循环本质是调用了__itre_方法
            yield 1
            yield 2
    
    
    # 本质上使用关键字class创建类时,就是调用了type函数来创建一个名为Foo的类。元组里面是父类,字典里面是类属性。
    # r = Foo('item')  # 执行__init__方法
    # # print(r())  # 执行__call__方法
    # r['item'] = 'lanxing'  # r.__setitem__('item','lanxing')
    # print(r['item'])  # r.__getitem__('item')
    # del r['item']  #
    # print(r[1:3])  #
    # r[1:3] = [11, 22, 33]
    # del r[1]
    print(Foo, type(Foo))
    # print(r.__dict__)  # 获取对象的所有属性与值,以字典形式返回
    # {'key': [11, 22, 33]}
    # print(Foo.__dict__)  # 获取类的所有属性与值,以字典形式返回
    '''
    {'__module__': '__main__', 
    '__init__': <function Foo.__init__ at 0x0000020458CC08C8>, 
    '__call__': <function Foo.__call__ at 0x0000020458CC0950>, 
    '__getitem__': <function Foo.__getitem__ at 0x0000020458CC09D8>, 
    '__setitem__': <function Foo.__setitem__ at 0x0000020458CC0A60>, 
    '__delitem__': <function Foo.__delitem__ at 0x0000020458CC0AE8>, 
    '__iter__': <function Foo.__iter__ at 0x0000020458CC0B70>, 
    '__dict__': <attribute '__dict__' of 'Foo' objects>, 
    '__weakref__': <attribute '__weakref__' of 'Foo' objects>, 
    '__doc__': None}
    '''
    # for i in r:  # 本质是调用了__iter__方法
    #     print(i)
    # dic = dict(k1=11, k2=22)
    # print(dic['k1'])
    # del dic['k2']
    # print(dic)
    

    1.3 元类__metaclass__

    元类的理解,这篇文章有助于理解元类。
    使用元类
    就是函数,方法调过来调过去,得使用几次才能理解元类。

    class MyType(type):
        def __init__(self, what, base=None, dict=None, *args, **kwargs):
            super().__init__(what, base=None, dict=None, *args, **kwargs)
    
        def __call__(self, *args, **kwargs):
            obj = self.__new__(self, *args, **kwargs)
            self.__init__(obj)
    
    
    class classname(metaclass=MyType):
        __metaclass__ = MyType  # 声明其元类是MyType
    
        def __init__(self, name, *args, **kwargs):
            self.name = name
            super().__init__(*args, **kwargs)
    
        def __new__(cls, *args, **kwargs):
            return object.__new__(cls, *args, **kwargs)
    
    
    # 第一阶段,解释器从上到下执行代码创建Foo类
    # 第二阶段,通过Foo类创建obj对象
    
    # Foo2 = type('Foo2', (object, ), {'func': lambda x: x + 2, 'name': 'lanxing'}) #关键字class本质是执行了type(class,base,dict=None)方法
    

    23. exception异常的处理

    23.1 引入异常

    异常的写法,把子类往前放,把父类往后放。可以存在多个except分支,一个except分支执行后,其他的就不会再次执行了。

    '''
    异常处理:
        需求:
            从键盘输入被除数与除数,求商并打印结果
    1,输入的数据类型问题:valueError
    2,ZeroDivisionError:division by zero
    try-except-finally
    
    '''
    # 这种写法太耗费程序员精力了,语法也不简洁。
    # if a.isdigit() and b.isdigit():
    #     a1 = int(a)
    #     b1 = int(b)
    #     if b != 0:
    #         c = a/b
    #         print('商为:{0}'.format(c))
    #     else:
    #         print('ZeroDivisionError:division by zero')
    #         print('除数不能为0')
    a = input('请输入被除数:》》》')
    b = input('请输入除数:》》》')
    try:
        a1 = int(a)
        b1 = int(b)
        c = a/b
        print('mod = {0}'.format(c))
    # 一旦捕获到异常,try里面异常后面的语句就不会被执行了。
    # 异常只会执行一次。
    
    # 捕获异常方式用法一:
    # except:
    #     print('输入类型有误或者除数为0')
    
    # 捕获异常方式用法二:
    # except Exception as e:#捕获异常并存储到e上
    #     print(type(e))
    #     print('输入类型有误或者除数为0')
    
    # 捕获异常方式用法三(提倡这种写法):
    # except ValueError:
    #     print('输入类型有误')
    # except ZeroDivisionError:
    #     print('除数为0错误')
    # except Exception:
    #     print('遇到异常')
    
    # 捕获异常方式用法四,这种写法与用法三会有区别:
    # except (ValueError,ValueError) as e:
    #     print('输入类型有误或除数为0')
    
    # 捕获异常方式用法五:
    except ValueError as e :
        print(e)
    except Exception:
        print('遇到异常')
    

    23.2 try-except-else-finally

    '''
    try:将有可能出异常的代码纳入try语句
    except:捕获异常,有多种写法
    else:可有可无,没有except就执行else
    finally:最后执行,不管前面什么情况,都最终执行。
    '''
    
    try:
        file = open('123.txt','r',encoding='utf-8')
        content = file.read()
        print(content)
    except Exception as e:
        print(e.args)
    else:
        print('没有异常')
    finally:
        file.close()
    

    23.3 异常的传递过程

    def test1():
        print('---'*10+'test1开始'+'---'*10)
        try:
            print(aa)
        except:
            pass
        print('---' * 10 + 'test1结束' + '---' * 10)
    
    def test2():
        print('---'*10+'test2开始'+'---'*10)
        # try:
        #     test1()
        # except:
        #     pass
    
        print('---' * 10 + 'test2结束' + '---' * 10)
    
    def test3():
        print('---'*10+'test3开始'+'---'*10)
        # try:
        #     test2()
        # except:
        #     pass
        print('---' * 10 + 'test3结束' + '---' * 10)
    
    test3()
    

    23.4 自定义异常

    先定义一个Exception的子类,然后再在调用处使用raise语句。

    '''
    自定义异常:
        自己创建异常类,一定要继承自Exception.
        抛出异常 raise 异常对象
    '''
    
    class GenderError(Exception):
        def __init__(self):
            self.errMsg = '性别异常,只能设置为男或女'
    
    
    class Student():
        def __init__(self,name,gender):
            self.name = name
            self.setGender(gender)
    
        def setGender(self,gender):
            if gender in ('男','女'):
                self.__gender = gender
            else:
                raise GenderError()
    
        def getGender(self):
            return  self.__gender
    
    stu1 = Student('刘忙','男')
    try:
        stu1.setGender('未知')
    except Exception as e:
        print(type(e))
        print(e.args)
        print(e.errMsg)
    
    
  • 相关阅读:
    Lotto--poj2245
    Avoid The Lakes--poj3620
    Fire Net--hdu1045
    变形课--hdu1181
    Apache Mina入门实例
    谈谈项目
    设计模式之装饰者模式
    linux下的权限控制
    centos 6.5 搭建JSP运行环境
    centos 6.5 搭建ftp服务器
  • 原文地址:https://www.cnblogs.com/lanxing0422/p/pythonday11.html
Copyright © 2011-2022 走看看