zoukankan      html  css  js  c++  java
  • Python-警告处理

    python 下Warning的使用

    起因是这样的,当我使用pymysql模块执行建表的sql语句时获,在控制台输出了红色的消息,但是程序并没有终止而是继续运行了

    sql语句如下:

    CREATE TABLE IF NOT EXISTS test(age int);
    

    整体代码:

    import pymysql
    conn = pymysql.connect(
        user= "root",
        password="",
        database="test"
    )
    
    c = conn.cursor()
    c.execute("create table if not exists abc(age int)")
    

    得到的警告信息如下:

    """
    NoneType: None
    /Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/pymysql/cursors.py:170: Warning: (1050, "Table 'abc' already exists")
      result = self._query(query)
    """
    Process finished with exit code 0
    

    sql语句是如果表存在则放弃创建,这意味着这个警告是应该的,并没有逻辑上的错误,但是这个红色的消息,让人看着不爽,于是找到了如下解决方案:

    from warnings import filterwarnings
    filterwarnings("ignore",category=pymysql.Warning)
    

    问题得到解决,作为强迫症患者,必须在深入研究一下,得出以下结论:

    warning模块中主要的两个方法

    1.warn

    该方法用于输出一个警告信息 
    #参数一: message 表示警告的详细信息
    #参数二: category 类别,需要一个类作为参数,该类必须是Warning的子类,Warning类是Exception的子类,用于给警告设置一个具体的类型
    #参数三: stacklevel 指定调用栈的层级,用于确定要从哪一级获取行号
    #参数四: 没研究
    

    stacklevel在源码中的调用:

    image-20190722221550778

    上述代码获得一个frame,用于获取行号

    image-20190722221746845

    由以上源码可以get到一个小技能即获取行号

    python获取行号:

    import sys
    f = sys._getframe() # f 是一个对象class为 frame 但是该类无法直接访问,猜想是系统底层隐藏的毕竟与解释器核心数据相关
    print(f.f_lineno) # f_lineno就是用于获取行号的属性
    
    """
    在源码中可以看到_getframe函数是可以给一个整型参数的,
    经过测试,得出结论,该参数用于,指定从栈的哪一个位置获取行号,
    """
    
    #测试代码:
    1 import sys
    2 def task():
    3    f = sys._getframe(2)
    4    print(f.f_lineno)
    5 
    6 def task2():
    7    task()
    8 
    9 task2()
    
    """
    0表示从当前位置,即执行_getframe的地方 
    1表示获取上一级调用位置的行号 即第7行
    2表示上上级 即第9行 以此类推...  
    """
    

    2.filterwarnings

    该方法用于过滤警告信息 
    #参数action:    表示如何处理这个警告
    							 可选的值 "error", "ignore", "always", "default", "module","once"
      						 error会将警告作为异常抛出
        					 ignore表示忽略该类警告不会打印
          				 once表示该相同类型相同消息的警告仅打印一次
    #参数category:  需要一个类,表示是要过滤的警告类别
    #参数module:    需要一个模块,表示是要过滤的模块名称
    #参数lineno:		一个整型,表示要过滤哪一行的警告 0表示所有行  其他值貌似没有作用
    

    意外发现

    在查看源码是,发现了一个用于表示警告消息的类

    image-20190722230232847

    该类非常简单,就是保存了一些警告信息,然后覆盖了 __str__函数,用于自定义字符串形式

    其中的初始化函数引起了我的注意,分析了一下,发现这个写法不错,可以简化初始化中的属性赋值操作于是做了一下实验:

    # 通用的类初始化方法
    class Person():
        def __init__(self,a,b,c):
            for k,v in locals().items():
                if k != "self":
                    setattr(self,k,v)
    
    p = Person(1,2,3)
    print(p.a)
    print(p.b)
    
    

    该方法最大的好处在于,无论初始化方法中需要多少参数都可以一一赋值,对于初始化参数多的类非常友好;

    其原理是通过locals()来获取函数中的局部变量的字典形式,然后遍历字典,排除self之后其他的都设置为self的属性,用形参的名字作为熟悉名,大大减少了一堆重复的赋值代码!

    否则你的代码可能是这样的:

    class Person():
        def __init__(self,a,b,c,d):
            self.a = a
            self.b = b 
            self.c = c
            self.d = d
    
    p = Person(1,2,3,4)
    print(p.a)
    print(p.b)
    print(p.c)
    

    如果参数特比多的话,你懂的......

  • 相关阅读:
    在Ubuntu 桌面版 12.04 LTS安装并运行SSH
    将Tp-link无线路由器桥接到Dlink无线路由器上
    如何解决Win7将任务栏程序自动分组的困扰
    安装Ubuntu 桌面版 12.04 LTS 过程之记录
    #lspci | grep Eth
    做技术不能人云亦云
    如何使用FF的Firebug组件中的net工具查看页面元素加载消耗时间
    在Fedora8上安装使用ActiveMQ5.8
    多态继承中的内存图解 && 多态中的对象变化的内存图解
    孔子装爹案例_帮助理解多态的成员访问特点及转型
  • 原文地址:https://www.cnblogs.com/yangyuanhu/p/11229128.html
Copyright © 2011-2022 走看看