起因是这样的,当我使用pyMysqL模块执行建表的SQL语句时获,在控制台输出了红色的消息,但是程序并没有终止而是继续运行了
SQL语句如下:
CREATE table IF NOT EXISTS test(age int);
整体代码:
import pyMysqLconn = 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 filterwarningsfilterwarnings("ignore",category=pyMysqL.Warning)
问题得到解决,作为强迫症患者,必须在深入研究一下,得出以下结论:
warning模块中主要的两个方法 1.warn该方法用于输出一个警告信息 #参数一: message 表示警告的详细信息#参数二: category 类别,需要一个类作为参数,该类必须是Warning的子类,Warning类是Exception的子类,用于给警告设置一个具体的类型#参数三: stacklevel 指定调用栈的层级,用于确定要从哪一级获取行号#参数四: 没研究
stacklevel在源码中的调用:
上述代码获得一个frame,用于获取行号
由以上源码可以get到一个小技能即获取行号
python获取行号:import sysf = sys._getframe() # f 是一个对象class为 frame 但是该类无法直接访问,猜想是系统底层隐藏的毕竟与解释器核心数据相关print(f.f_lineno) # f_lineno就是用于获取行号的属性"""在源码中可以看到_getframe函数是可以给一个整型参数的,经过测试,得出结论,该参数用于,指定从栈的哪一个位置获取行号,"""#测试代码:1 import sys2 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表示所有行 其他值貌似没有作用意外发现
在查看源码是,发现了一个用于表示警告消息的类
该类非常简单,就是保存了一些警告信息,然后覆盖了 __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,c,d): self.a = a self.b = b self.c = c self.d = dp = Person(1,3,4)print(p.a)print(p.b)print(p.c)
如果参数特比多的话,你懂的......
总结以上是内存溢出为你收集整理的Python-警告处理全部内容,希望文章能够帮你解决Python-警告处理所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)