赞
踩
可向用户反馈报错信息。异常也是对象,可对他进行操作。所有的异常都是基类Exception的成员,异常是在exceptions模块中定义,Python自动将所有异常名称放在内建命名空间中,所以程序不必导入exceptions模块即可使用异常。
一旦引发而且没有捕捉SystemExit异常,程序执行就会终止。如果交互式会话遇到一个未被捕捉的SystemExit异常,会话就会终止。
异常是指程序运行时引发的错误,原因有除零、下标越界、文件不存在、网络异常、类型错误、名字错误、字典键错误、磁盘空间不足 、文件不存在、路径写错 缩进错误 将赋值运算符 = 和比较运算符==混淆
当Python解释 器遇到异常情况时,它会停止程序的运行,然后显示一个追踪(traceback) 信息。
SyntaxError;语法
IndentationError:缩进
TypeError: 数值不可修改 连接字符串和非字符串 忘记为类中第一个方法添加self
NameError : 变量没有定义
内置异常
定义在exceptions模块中,此模块在Python解释器启动时就会自动加载
编写程序接受用户输入,且要求用户必须输入整数,不接收其他类型的输入。
- >>>while True:
- x = input('Please input:')
- try:
- x = int(x)
- print('You have input {0}'.format(x))
- break
- except Exception as e:
- print('Error.')
Please input:234c
Error.
Please input:5
You have input 5
- >>>while True:
- x = input('Please input:')
- try:
- x = int(x)
- except Exception as e:
- print('Error')
- else:
- print('You have input [0]'.format(x))
- break
Please input:888c
Error.
Please input:888
You have input 888
- filename = input('请输入一个文件名:')
- try:
- fp = open(filename) #尝试打开文件
- try: #尝试读取数据并计算和输出
- print(int(fp.read())+5)
- except: #读取文件或计算失败时执行的代码
- print('文件内容格式不正确。')
- finally: #确保文件能够关闭
- fp.close()
- except: #打开文件失败时执行的代码
- print('文件不存在')
异常类的实例和清除异常
每当有一一个异常被输出时,该异常类就会创建一个实例,此实例继承了异常类的所有属性。(最 重要的就是args属性)
- try:
- x = [1,2,3]
- print(x[4])
- except IndexError as err :
- print(err.args[0])
-
- list index out of range
IndexError: list index out of range
- >>>try:
- x = float(input('请输入整数:'))
- y = float(input('请输入除数:'))
- z = x / y
- except ZeroDivisionError:
- print('除数不能为零')
- except ValueError:
- print('被除数和除数应为数值类型')
- except NameError:
- print('变量不存在')
- else:
- print(x,'/',y,'=',z)
- >>> a = 3
-
- >>> b = 5
-
- >>> assert a==b, 'a must be equal to b'
-
-
-
- AssertionError: a must be equal to b
发生异常时Python能够记住引发的异常以及程序的当前状态,Python还维护着traceback(跟踪)对象,其中含有异常发生时与函数调用堆栈有关的信息,异常可能在一系列嵌套较深的函数调用中引发,程序调用每个函数时,Python会在“函数调用堆栈”的起始处插入函数名,一旦异常被引发 ,Python会搜索一个相应的异常处理程序。
如果当前函数中没有异常处理程序,当前函数会终止执行,Python会搜索当前函数的调用函数,并以此类推,直到发现匹配的异常处理程序,或者Python抵达主程序为止,这一查找合适的异常处理程序的过程就称为“堆栈辗转开解”(Stack Unwinding)。解释器一方面维护着与放置堆栈中的函数有关的信息,另一方面也维护着与已从堆栈中“辗转开解”的函数有关的信息。
- try:
- block
- except:
- traceback.print_exc()
sys模块
sys模块中的exc_info()函数,可以取得目前正在处理的异常信息exc_info()函数会返回一个元组,这个元组包括三个元素。
- import sys
- try:
- 12/0
- except:
- info = sys.exc_info()
- exc_type = info[0]
- exc_value = info[1]
- exc_traceback = info[2]
- print(ecx_type,':',exc_value)
- import sys
- try:
- 12/0
- except :
- info=sys.exc_ info( )
- exc_ type=info[0]
- exc_ value = info[1]
- exc_ traceback = info[2]
- print(exc_ type, " :" ,exc_ value )
- <class ' ZeroDivisionError'> : division by zero
traceback对象
使用sys模块的exc_ info() 函数返回值的第三个元素,会返回一个traceback对象。
traceback对象的接口函数可以捕捉、格式化,或是输出Python程序的堆栈追踪(traceback) 信息。
- import traceback
- try:
- 12/0
- except :
- traceback.print exc()
-
-
- Traceback (most recent call last) ;
- File "<ipython- input- 19- 71f6b5a77e1e>", line 4, in <module>
- 12/0
- ZeroDivisionError: division by zero
抛出异常
raise NameError ('抛出了一个异常')
- raise NameError( '这里是raise抛出的-个异常' )
-
-
- NameError
- Traceback (most recent cal1 last )
- <ipython- input- 20-e274246dfc1f> in <module>
- ----> 1 raise NameError( '这里是raise抛出的一个异常')
- NameError:这里是raise抛出的一 个异常
结束解释器的运行
用户可以利用输出SystemExit异常,来强迫结束解释器的运行
使用sys.exit()函数会输出一个SystemExit异常,sys.exit()会结束线程
- import sys
-
- try:
- sys.exit()
- except SystemExit:
- print('目前还不能结束解释器运行')
-
- #如果想正常结束解释器运行,最好利用OS模块的_exit()函数
使用raise语句离开嵌套循环
- class ExitLoop(Exception):
- pass
-
- try:
- i = 1
- while i < 10:
- for j in range(1, 10):
- print(i, j)
- if (i == 2) and (j == 2):
- raise(ExitLoop)
- i += 1
- except ExitLoop:
- print('当i = 2, j = 2时离开嵌套循环')
1 1
2 2
当i=2,j=2时离开循环嵌套
- class URLError(Exception):
- pass
-
- try:
- raise URLError(“URL ERROR”)
- except URLError as err:
- print(err.args[0])
URL ERROR
原理:检查表达式的代码当表达式求值为真,一切正常;但若表达式求值为假,则暂停程序,打印消息,并在可行的情况下启动调试器。
- assert <测试码>[, 参数]
- #原理
-
- a = 10
- assert (a != 0),"Error happened, a = 0"
- print(a)
如果a = 0会抛出 Error happened a = 0
- if __debug__:
- if not (<测试码>):
- raise AssertionError [, 参数]
-
- import types
- def checkType(arg):
- if__debug__:
- if not (type(arg) == str):
- raise AssertionError("参数类型不是字符串")
-
- checkType(1)
Asser t ionError
Traceback (most recent ca11 last)
<ipython- input- 30-c6dc6612ea27> in <module>
5
raise AssertionError("参 数类型不是字符串")
6
----> 7 checkType(1)
<ipython- input-30-c6dc6612ea27> in checkType (arg)
3
debug__
4
if not (type(arg) == str):
----> 5
raise AssertionError("参 数类型不是字符串")
6
7 checkType(1)
AssertionError:参数类型不是字符串
with open(filename, mode, encoding) as fp:
# 通过文件对象fp操作文件的代码
tkinter是Python标准库,不需要额外安装就可以直接使用,比较方便,得到了很多人的青睐,成为现在做GUI开发的主流模块。除了在tkinter库的主模块中提供了大量组件,还通过其中的模块tkinter.ttk提供了Combobox、Progressbar和Treeview等组件,tkinter.scrolledtext提供了带滚动条的文本框,messagebox、commondialog、dialog、colorchooser、simpledialog、filedialog等模块提供了各种形式的对话框。
组件名称 | 说明 |
Button | 按钮 |
Canvas | 画布,用于绘制直线、椭圆、多边形等各种图形 |
Checkbutton | 复选框形式的按钮 |
Entry | 单行文本框 |
Frame | 框架 |
Label | 标签,常用来显示文本 |
Listbox | 列表框 |
Menu | 菜单 |
Message | 多行文本框 |
Radiobutton | 单选框 |
Scrollbar | 滚动条 |
Toplevel | 创建新窗口 |
编写通用代码,例如数据库操作
搭建界面,放置组件,设置组件属性,可以借助PAGE
编写组件的事件处理代码
启动应用程序,启动消息主循环
- import tkinter
- import tkinter.messagebox
- import os
- import os.path
-
- path = os.getenv('temp')
- filename = os.path.join(path, 'info.txt')
- #创建应用程序窗口
- root = tkinter.Tk()
- #定义窗口大小
- root['height'] = 140
- root['width'] = 200
-
- #在窗口上创建标签组件
- labelName = tkinter.Label(root,
- text='User Name:',
- justify=tkinter.RIGHT,
- anchor = 'e',
- width=80)
- #把组件放置到窗口上指定区域
- labelName.place(x=10, y=5, width=80, height=20)
-
- varName = tkinter.StringVar(root, value='')
- entryName = tkinter.Entry(root,
- width=80,
- textvariable=varName)
- entryName.place(x=100, y=5, width=80, height=20)
-
- labelPwd = tkinter.Label(root,
- text='User Pwd:',
- justify=tkinter.RIGHT,
- anchor = 'e',
- width=80)
- labelPwd.place(x=10, y=30, width=80, height=20)
-
- #创建密码文本框
- varPwd = tkinter.StringVar(root, value='')
- entryPwd = tkinter.Entry(root,
- show='*', #不管输入什么,都显示星号
- width=80,
- textvariable=varPwd)
- entryPwd.place(x=100, y=30, width=80, height=20)
-
- #尝试自动填写用户名和密码
- try:
- with open(filename) as fp:
- n, p = fp.read().strip().split(',')
- varName.set(n)
- varPwd.set(p)
- except:
- pass
- #记住我,复选框
- rememberMe = tkinter.IntVar(root, value=1)
- checkRemember = tkinter.Checkbutton(root,
- text='Remember me?',
- variable=rememberMe,
- onvalue=1,
- offvalue=0)
- checkRemember.place(x=30, y=70, width=120, height=20)
-
- #登录按钮事件处理函数
- def login():
- #获取用户名和密码
- name = entryName.get()
- pwd = entryPwd.get()
- if name=='admin' and pwd=='123456':
- tkinter.messagebox.showinfo(title='恭喜',
- message='登录成功!')
- if rememberMe.get() == 1:
- #把登录成功的信息写入临时文件
- with open(filename, 'w') as fp:
- fp.write(','.join((name,pwd)))
- else:
- try:
- #删除用于记录用户名和密码的临时文件
- os.remove(filename)
- except:
- pass
- else:
- tkinter.messagebox.showerror('警告',
- message='用户名或密码错误')
- #创建按钮组件,同时设置按钮事件处理函数
- buttonOk = tkinter.Button(root,
- text='Login', #设置按钮上显示的文本
- command=login) #设置按钮的单击事件处理函数
- buttonOk.place(x=30, y=100, width=50, height=20)
-
- #取消按钮的事件处理函数
- def cancel():
- #清空用户输入的用户名和密码
- varName.set('')
- varPwd.set('')
- buttonCancel = tkinter.Button(root,
- text='Cancel',
- command=cancel)
- buttonCancel.place(x=90, y=100, width=50, height=20)
- #启动消息循环
- root.mainloop()
- 例12-2 tkinter单选钮、复选框、组合框、列表框综合运用案例。
- import tkinter
- import tkinter.messagebox
- import tkinter.ttk
-
- #创建tkinter应用程序
- root = tkinter.Tk()
- #设置窗口标题
- root.title('Selection widgets')
- #定义窗口大小
- root['height'] = 400
- root['width'] = 320
-
- #与姓名关联的变量
- varName = tkinter.StringVar()
- varName.set('')
- #创建标签,然后放到窗口上
- labelName = tkinter.Label(root,
- text='Name:',
- justify=tkinter.RIGHT,
- width=50)
- labelName.place(x=10, y=5, width=50, height=20)
- #创建文本框,同时设置关联的变量
- entryName = tkinter.Entry(root,
- width=120,
- textvariable=varName)
- entryName.place(x=70, y=5, width=120, height=20)
-
- labelGrade = tkinter.Label(root,
- text='Grade:',
- justify=tkinter.RIGHT, width=50)
- labelGrade.place(x=10, y=40, width=50, height=20)
- #模拟学生所在年级,字典键为年级,字典值为班级
- studentClasses = {'1':['1', '2', '3', '4'],
- '2':['1', '2'],
- '3':['1', '2', '3']}
- #学生年级组合框
- comboGrade = tkinter.ttk.Combobox(root,width=50,
- values=tuple(studentClasses.keys()))
- comboGrade.place(x=70, y=40, width=50, height=20)
- #事件处理函数
- def comboChange(event):
- grade = comboGrade.get()
- if grade:
- #动态改变组合框可选项
- comboClass["values"] = studentClasses.get(grade)
- else:
- comboClass.set([])
- #绑定组合框事件处理函数
- comboGrade.bind('<<ComboboxSelected>>', comboChange)
-
- labelClass = tkinter.Label(root,
- text='Class:',
- justify=tkinter.RIGHT, width=50)
- labelClass.place(x=130, y=40, width=50, height=20)
- #学生班级组合框
- comboClass = tkinter.ttk.Combobox(root, width=50)
- comboClass.place(x=190, y=40, width=50, height=20)
-
- labelSex = tkinter.Label(root,
- text='Sex:',
- justify=tkinter.RIGHT, width=50)
- labelSex.place(x=10, y=70, width=50, height=20)
- #与性别关联的变量,1:男;0:女,默认为男
- sex = tkinter.IntVar()
- sex.set(1)
- #单选钮,男
- radioMan = tkinter.Radiobutton(root,
- variable=sex,
- value=1,
- text='Man')
- radioMan.place(x=70, y=70, width=50, height=20)
- #单选钮,女
- radioWoman = tkinter.Radiobutton(root,
- variable=sex,
- value=0,
- text='Woman')
- radioWoman.place(x=130, y=70, width=70, height=20)
-
- #与是否班长关联的变量,默认当前学生不是班长
- monitor = tkinter.IntVar()
- monitor.set(0)
- #复选框,选中时变量值为1,未选中时变量值为0
- checkMonitor = tkinter.Checkbutton(root,
- text='Is Monitor?',
- variable=monitor,
- onvalue=1,
- offvalue=0)
- checkMonitor.place(x=20, y=100, width=100, height=20)
- #添加按钮单击事件处理函数
- def addInformation():
- result = 'Name:' + entryName.get()
- result = result + ';Grade:' + comboGrade.get()
- result = result + ';Class:' + comboClass.get()
- result = result + ';Sex:'\
- + ('Man' if sex.get() else 'Woman')
- result = result + ';Monitor:'\
- + ('Yes' if monitor.get() else 'No')
- #把信息插入到列表框组件中
- listboxStudents.insert(0, result)
- buttonAdd = tkinter.Button(root,
- text='Add',
- width=40,
- command=addInformation)
- buttonAdd.place(x=130, y=100, width=40, height=20)
-
- #删除按钮的事件处理函数
- def deleteSelection():
- selection = listboxStudents.curselection()
- if not selection:
- tkinter.messagebox.showinfo(title='Information',
- message='No Selection')
- else:
- listboxStudents.delete(selection)
- buttonDelete = tkinter.Button(root,
- text='DeleteSelection',
- width=100,
- command=deleteSelection)
- buttonDelete.place(x=180, y=100, width=100, height=20)
-
- #创建列表框组件
- listboxStudents = tkinter.Listbox(root, width=300)
- listboxStudents.place(x=10, y=130, width=300, height=200)
-
- #启动消息循环
- root.mainloop()
-
- import os
- import tkinter
- import tkinter.simpledialog
- import tkinter.colorchooser
- import tkinter.filedialog
- #需要执行pip install pillow安装扩展库
- from PIL import ImageGrab
-
- root = tkinter.Tk()
- root.title('My Paint----by Dong Fuguo')
- root['width'] = 800
- root['height'] = 600
-
- #控制是否允许画图的变量,1:允许,0:不允许
- canDraw = tkinter.IntVar(value=0)
-
- what = tkinter.IntVar(value=1)
-
- #记录鼠标位置的变量
- X = tkinter.IntVar(value=0)
- Y = tkinter.IntVar(value=0)
-
- #前景色、背景色
- foreColor = '#000000'
- backColor = '#FFFFFF'
-
- #创建画布
- image = tkinter.PhotoImage()
- canvas = tkinter.Canvas(root,
- bg='white',
- width=800, height=600)
- canvas.create_image(800, 600, image=image)
-
- #鼠标左键单击,允许画图,并记录当前鼠标位置
- def onLeftButtonDown(event):
- canDraw.set(1)
- X.set(event.x)
- Y.set(event.y)
- if what.get()==4:
- canvas.create_text(event.x, event.y, text=text)
- canvas.bind('<Button-1>', onLeftButtonDown)
-
- #记录最后绘制图形的id
- lastDraw = 0
- #按住鼠标左键移动,画图
- def onLeftButtonMove(event):
- global lastDraw
- if canDraw.get()==0:
- return
- if what.get()==1:
- #使用当前选择的前景色绘制曲线
- canvas.create_line(X.get(), Y.get(), event.x,
- event.y, fill=foreColor)
- X.set(event.x)
- Y.set(event.y)
- elif what.get()==2:
- #绘制直线,先删除刚刚画过的直线,再画一条新的直线
- try:
- canvas.delete(lastDraw)
- except Exception as e:
- pass
- lastDraw = canvas.create_line(X.get(), Y.get(),
- event.x, event.y,
- fill=foreColor)
- elif what.get()==3:
- #绘制矩形,先删除刚刚画过的矩形,再画一个新的矩形
- try:
- canvas.delete(lastDraw)
- except Exception as e:
- pass
- lastDraw = canvas.create_rectangle(X.get(), Y.get(),
- event.x, event.y,
- fill=backColor,
- outline=foreColor)
- elif what.get()==5:
- #橡皮,使用背景色填充10*10的矩形区域
- canvas.create_rectangle(event.x-5, event.y-5,
- event.x+5, event.y+5,
- outline=backColor, fill=backColor)
- canvas.bind('<B1-Motion>', onLeftButtonMove)
-
- #鼠标左键抬起,不允许再画图了
- def onLeftButtonUp(event):
- if what.get()==2:
- #绘制直线
- canvas.create_line(X.get(),
- Y.get(),
- event.x,
- event.y,
- fill=foreColor)
- elif what.get()==3:
- #绘制矩形
- canvas.create_rectangle(X.get(),
- Y.get(),
- event.x,
- event.y,
- fill=backColor,
- outline=foreColor)
- canDraw.set(0)
- global lastDraw
- #防止切换图形时误删上次绘制的图形
- lastDraw = 0
- canvas.bind('<ButtonRelease-1>', onLeftButtonUp)
-
- #创建菜单
- menu = tkinter.Menu(root, tearoff=0)
- #打开图像文件
- def Open():
- filename = tkinter.filedialog.askopenfilename(title='Open Image',
- filetypes=[('image', '*.jpg *.png *.gif')])
- if filename:
- global image
- image = tkinter.PhotoImage(file=filename)
- canvas.create_image(80, 80, image=image)
- menu.add_command(label='Open', command=Open)
-
- def Save():
- #获取客户区域位置和尺寸,并截图保存
- left = int(root.winfo_rootx())
- top = int(root.winfo_rooty())
- width = root.winfo_width()
- height = root.winfo_height()
- im = ImageGrab.grab((left,top,left+width,top+height))
-
- #保存绘制的图片
- filename = tkinter.filedialog.asksaveasfilename(title='保存图片',
- filetypes=[('图片文件','*.png')])
- if not filename:
- return
- if not filename.endswith('.png'):
- filename = filename+'.png'
-
- im.save(filename)
- menu.add_command(label='Save', command=Save)
-
- #添加菜单,清除,遍历画布上的所有图像,逐个删除
- def Clear():
- for item in canvas.find_all():
- canvas.delete(item)
- menu.add_command(label='Clear', command=Clear)
- #添加分割线
- menu.add_separator()
-
- #创建子菜单,用来选择绘图类型
- menuType = tkinter.Menu(menu, tearoff=0)
- def drawCurve():
- what.set(1)
- menuType.add_command(label='Curve', command=drawCurve)
-
- def drawLine():
- what.set(2)
- menuType.add_command(label='Line', command=drawLine)
-
- def drawRectangle():
- what.set(3)
- menuType.add_command(label='Rectangle', command=drawRectangle)
-
- def drawText():
- global text
- text = tkinter.simpledialog.askstring(title='Input what you want to draw', prompt='')
- what.set(4)
- menuType.add_command(label='Text', command=drawText)
-
- menuType.add_separator()
-
- #选择前景色
- def chooseForeColor():
- global foreColor
- foreColor = tkinter.colorchooser.askcolor()[1]
- menuType.add_command(label='Choose Foreground Color',
- command=chooseForeColor)
-
- #选择背景色
- def chooseBackColor():
- global backColor
- backColor = tkinter.colorchooser.askcolor()[1]
- menuType.add_command(label='Choose Background Color',
- command=chooseBackColor)
-
- #橡皮
- def onErase():
- import tkinter
- import tkinter.messagebox
- import random
- import threading
- import itertools
- import time
-
- root = tkinter.Tk()
- # 窗口标题
- root.title('随机提问')
- # 窗口初始大小和位置
- root.geometry('260x180+400+300')
- # 不允许改变窗口大小
- root.resizable(False, False)
-
- # 关闭程序时执行的函数代码,停止滚动显示学生名单
- def closeWindow():
- # 标记flat变量为False,停止滚动
- root.flag = False
- # 暂停0.1秒,等待用于滚动名单的子线程结束
- time.sleep(0.1)
- # 销毁窗口,关闭程序
- root.destroy()
- # 绑定消息处理函数,当窗口关闭时会触发'WM_DELETE_WINDOW'消息
- root.protocol('WM_DELETE_WINDOW', closeWindow)
-
- # 模拟学生名单,这些学生姓名在窗口上滚动
- students = ['张三', '李四', '王五', '赵六', '周七', '钱八']
- # 变量,用来控制是否滚动显示学生名单,默认启动时不滚动
- root.flag = False
-
- # 用户滚动名单的线程函数
- def switch():
- root.flag = True
- # 随机打乱学生名单
- t = students[:]
- random.shuffle(t)
- # 创建cycle对象,用于实现无限重复的滚动
- t = itertools.cycle(t)
-
- # 一直滚动,直到flag的值为False
- while root.flag:
- # 滚动显示
- # 把第二个人名移动到第一个
- # 把第三个人名移动到第二个
- # 获取一个新的人名显示为第三个
- lbFirst['text'] = lbSecond['text']
- lbSecond['text'] = lbThird['text']
- lbThird['text'] = next(t)
-
- # 数字可以修改,控制滚动速度
- time.sleep(0.1)
-
- def btnStartClick():
- # 每次单击“开始”按钮创建并启动新线程
- t = threading.Thread(target=switch)
- t.start()
- # 把“开始”按钮禁用,避免重复响应单击操作
- btnStart['state'] = 'disabled'
- # 启用“停”按钮
- btnStop['state'] = 'normal'
- btnStart = tkinter.Button(root,
- text='开始',
- command=btnStartClick)
- btnStart.place(x=30, y=10, width=80, height=20)
-
- def btnStopClick():
- # 单击“停”按钮结束滚动显示
- root.flag = False
- # 等待0.3秒,彻底停止滚动之后再获取中奖的人名
- time.sleep(0.3)
- tkinter.messagebox.showinfo('恭喜',
- '本次中奖:'+lbSecond['text'])
- # 启用“开始”按钮,禁用“停”按钮
- btnStart['state'] = 'normal'
- btnStop['state'] = 'disabled'
- btnStop = tkinter.Button(root,
- text='停',
- command=btnStopClick)
- # 程序启动时,“停”按钮初始设置为禁用
- btnStop['state'] = 'disabled'
- btnStop.place(x=150, y=10, width=80, height=20)
-
- # 用来滚动显示学生名单的3个Label组件
- # 可以根据需要进行添加,但要修改上面的线程函数代码
- lbFirst = tkinter.Label(root, text='')
- lbFirst.place(x=80, y=60, width=100, height=20)
-
- # 红色Label组件,表示中奖名单
- lbSecond = tkinter.Label(root, text='')
- lbSecond['fg'] = 'red'
- lbSecond.place(x=80, y=90, width=100, height=20)
-
- lbThird = tkinter.Label(root, text='')
- lbThird.place(x=80, y=120, width=100, height=20)
-
- # 启动消息主循环,启动应用程序
- root.mainloop()
- 例12-7 使用tkinter实现计算器程序
-
- import re
- import tkinter
- import tkinter.messagebox
-
- root = tkinter.Tk()
- # 设置窗口大小和位置
- root.geometry('300x270+400+100')
- # 不允许改变窗口大小
- root.resizable(False, False)
- # 设置窗口标题
- root.title('简易计算器-董付国')
-
- # 字符串变量
- contentVar = tkinter.StringVar(root, '')
- # 用来显示表达式的文本框,设置关联变量
- contentEntry = tkinter.Entry(root, textvariable=contentVar)
- # 设置为只读,只能通过按钮来输入要计算的表达式
- contentEntry['state'] = 'readonly'
- contentEntry.place(x=10, y=10, width=280, height=20)
-
- # 按钮通用代码,参数btn表示按钮的是哪个按钮
- def buttonClick(btn):
- content = contentVar.get()
- # 如果已有内容是以小数点开头的,前面加0
- if content.startswith('.'):
- content = '0' + content
-
- # 根据不同按钮做出相应的处理
- if btn in '0123456789':
- # 普通数字按钮,直接连接到表达式最后
- content += btn
- elif btn == '.':
- # 如果最后一个运算数中已经有小数点,就提示错误
- lastPart = re.split(r'\+|-|\*|/]', content)[-1]
- if '.' in lastPart:
- tkinter.messagebox.showerror('错误', '小数点太多了')
- return
- else:
- # 最后一个运算数中没有小数点,把小数点连接到最后
- content += btn
- elif btn == 'C':
- # 清除整个表达式
- content = ''
- elif btn == '=':
- # 按下等于号按钮,计算结果
- try:
- # 尝试对输入的表达式求值
- content = str(eval(content))
- except:
- tkinter.messagebox.showerror('错误', '表达式错误')
- return
- elif btn in operators:
- # 按下运算符按钮,表达式中不允许有连续的运算符
- if content.endswith(operators):
- tkinter.messagebox.showerror('错误',
- '不允许存在连续运算符')
- return
- content += btn
- elif btn == 'Sqrt':
- # 求平方根
- # 切分出整数部分和小数部分
- n = content.split('.')
- # 要求小数点前后都是数字,如果表达式中含有运算符,不符合要求
- if all(map(lambda x: x.isdigit(), n)):
- content = eval(content) ** 0.5
- else:
- tkinter.messagebox.showerror('错误', '表达式错误')
- return
- # 显示计算结果
- contentVar.set(content)
-
- # 放置清除按钮和等号按钮
- btnClear = tkinter.Button(root,
- text='Clear',
- command=lambda:buttonClick('C'))
- btnClear.place(x=40, y=40, width=80, height=20)
- btnCompute = tkinter.Button(root,
- text='=',
- command=lambda:buttonClick('='))
- btnCompute.place(x=170, y=40, width=80, height=20)
-
- #放置10个数字、小数点和计算平方根的按钮
- digits = list('0123456789.') + ['Sqrt']
- index = 0
- for row in range(4):
- for col in range(3):
- d = digits[index]
- index += 1
- btnDigit = tkinter.Button(root,
- # 按钮上显示的内容
- text=d,
- # 按下按钮时执行的函数
- command=lambda x=d:buttonClick(x))
- # 把按钮放置到窗口上
- btnDigit.place(x=20+col*70,
- y=80+row*50,
- width=50,
- height=20)
-
- # 放置运算符按钮
- operators = ('+', '-', '*', '/', '**', '//')
- for index, operator in enumerate(operators):
- btnOperator = tkinter.Button(root,
- text=operator,
- command=lambda x=operator:buttonClick(x))
- btnOperator.place(x=230, y=80+index*30, width=50, height=20)
-
- # 启动消息主循环,启动应用程序
- root.mainloop()
- 例12-8 使用tkinter实现定时自动关闭的窗口
-
- import time
- import tkinter
- import threading
-
- # 创建应用程序窗口,设置标题和大小
- root = tkinter.Tk()
- root.title('倒计时自动关闭的窗口')
- root['width'] = 400
- root['height'] = 300
- # 不允许改变窗口大小
- root.resizable(False, False)
-
- # 创建Text组件,放置一些文字
- richText = tkinter.Text(root, width=380)
- richText.place(x=10, y=10, width=380, height=230)
- # 连续插入5行内容
- # '0.0'表示插入位置,第0行第0列
- # 如果想让插入的内容占一行,需要在字符串最后有换行符
- for i in range(5):
- # f字符串语法,会把{i}替换为i的当前实际值
- richText.insert(f'{i}.0',
- '假设阅读这些文字需要10秒钟时间\n')
-
- # 显示倒计时的Label
- lbTime = tkinter.Label(root, fg='red', anchor='w')
- lbTime.place(x=10, y=250, width=150)
-
- def autoClose():
- # 倒计时10秒钟
- for i in range(10):
- # f字符串语法,对{}中的表达式进行计算并替换
- lbTime['text'] = f'距离窗口关闭还有{10-i}秒'
- # 每秒钟修改一次提示信息
- time.sleep(1)
- root.destroy()
- # 创建并启动线程
- t = threading.Thread(target=autoClose)
- t.start()
-
- # 启动消息主循环,启动应用程序
- root.mainloop()
-
- import time
- import tkinter
- import threading
-
- # 创建应用程序窗口,设置标题和大小
- root = tkinter.Tk()
- root.title('倒计时自动关闭的窗口')
- root['width'] = 400
- root['height'] = 300
- # 不允许改变窗口大小
- root.resizable(False, False)
-
- # 创建Text组件,放置一些文字
- richText = tkinter.Text(root, width=380)
- richText.place(x=10, y=10, width=380, height=230)
- # 连续插入5行内容
- # '0.0'表示插入位置,第0行第0列
- # 如果想让插入的内容占一行,需要在字符串最后有换行符
- for i in range(5):
- # f字符串语法,会把{i}替换为i的当前实际值
- richText.insert(f'{i}.0',
- '假设阅读这些文字需要10秒钟时间\n')
-
- # 显示倒计时的Label
- lbTime = tkinter.Label(root, fg='red', anchor='w')
- lbTime.place(x=10, y=250, width=150)
-
- def autoClose():
- # 倒计时10秒钟
- for i in range(10):
- # f字符串语法,对{}中的表达式进行计算并替换
- lbTime['text'] = f'距离窗口关闭还有{10-i}秒'
- # 每秒钟修改一次提示信息
- time.sleep(1)
- root.destroy()
- # 创建并启动线程
- t = threading.Thread(target=autoClose)
- t.start()
-
- # 启动消息主循环,启动应用程序
- root.mainloop()
logging库日志级别
级别 级别数值 使用时机
DEBUG 10 详细信息,常用于调试。
INFO 20 程序正常运行过程中产“生的一些信息。
WARNING 30 警告用户,虽然程序还在正常工作,但有可能发生错误。
ERROR 40 由于更严重的问题,程序已不能执行一些功能了。
CRITICAL 50 严重错误,程序已不能继续运行。
- import logging
-
- #print("This is a 10g. text")
-
- logging. debug("This is debug log")
- logging.info("This is info Log")
- logging.warning("This is warning log")
- logging.error("This is error Log")
- logging.critical("This is critical log")
- WARNING: root:This is wa rning log
- ERROR: root:This is error Log
- CRITICAL : root:This is critical Log
-
- Process finished with exit code 0
- import logging
- #使用baseConfig( )来指定日志输出级别
- logging.basicConfig( leve1= logging. DEBUG)
- print("This is a log text")
- logging.debug("This is debug log" )
- logging.info("This is info log")
- logging.warning("This is warning log")
- logging.error("This is error log")
- logging.critical(This is critical log")
输出代码:
- DEBUG: root:This is debug log
- INFO: root:This is info log
- WARNING: root:This is warning log
- ERROR: root:This is error log
- CRITICAL: root:This is critical log
- This is a log text
logging . basicConfig( filename='demo,Log', fi lemode= 'w's leve (= Logging . DEBUG
新生成一个叫demo.log的文件 每次记录日志都会重新写入 不依次追加 默认是追加
- loggingbasicConfig(format="%(message)s", level=logging.DEBUG)
- name = “张三"
- age = 18
- logging.debug("姓名%s, 年龄%d", name, age )
可以只输出信息
- logging.basicConfig(format="%(asctime)s|%(LeveLnames|%(filename)s:% (lineno)s|% (message)s
- ", leve L= logging. DEBUG)
-
2021-09-16 11:07:52, 161 DEBUG|2.2py:10|姓名张三,年龄18
日志logging
高级应用,四个组件:
Loggers:记录器
Handlers:处理器
Filters:过滤器
Formatters:格式化器
- import logging
- import logging.config
-
- #配置文件的方式来处理日志
- logging.config.fileConfig('logging.config')
-
- logger = logging.getLogger('applog')
-
- #打印日志
- logger.debug("This is a debug log")
- logger.info("This is a info log")
- logger.warning("This is a warning log")
- logger.error("This is a error log")
- logger.critical("This is a critical log")
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。