python怎么消除警告_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在源码中的调用:

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

由以上源码可以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表示所有行 其他值貌似没有作用

意外发现

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

该类非常简单,就是保存了一些警告信息,然后覆盖了 __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)

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值