当前位置:   article > 正文

异常和日志_不断接收新用户的的输入(要求输入整数,不接受其他类型的输入)并做除法运算

不断接收新用户的的输入(要求输入整数,不接受其他类型的输入)并做除法运算

概念

 可向用户反馈报错信息。异常也是对象,可对他进行操作。所有的异常都是基类Exception的成员,异常是在exceptions模块中定义,Python自动将所有异常名称放在内建命名空间中,所以程序不必导入exceptions模块即可使用异常。

一旦引发而且没有捕捉SystemExit异常,程序执行就会终止。如果交互式会话遇到一个未被捕捉的SystemExit异常,会话就会终止。

异常是指程序运行时引发的错误,原因有除零、下标越界、文件不存在、网络异常、类型错误、名字错误、字典键错误、磁盘空间不足 、文件不存在、路径写错 缩进错误 将赋值运算符 = 和比较运算符==混淆

当Python解释 器遇到异常情况时,它会停止程序的运行,然后显示一个追踪(traceback) 信息。
 

SyntaxError;语法
IndentationError:缩进

TypeError: 数值不可修改 连接字符串和非字符串  忘记为类中第一个方法添加self

NameError : 变量没有定义

内置异常
定义在exceptions模块中,此模块在Python解释器启动时就会自动加载
 


 

 

异常处理结构

try……except……

编写程序接受用户输入,且要求用户必须输入整数,不接收其他类型的输入。

  1. >>>while True:
  2. x = input('Please input:')
  3. try:
  4. x = int(x)
  5. print('You have input {0}'.format(x))
  6. break
  7. except Exception as e:
  8. print('Error.')

Please input:234c

Error.

Please input:5

You have input 5

try……except……else 

  1. >>>while True:
  2. x = input('Please input:')
  3. try:
  4. x = int(x)
  5. except Exception as e:
  6. print('Error')
  7. else:
  8. print('You have input [0]'.format(x))
  9. break

Please input:888c

Error.

Please input:888

You have input 888

try……except……finally

  1. filename = input('请输入一个文件名:')
  2. try:
  3. fp = open(filename) #尝试打开文件
  4. try: #尝试读取数据并计算和输出
  5. print(int(fp.read())+5)
  6. except: #读取文件或计算失败时执行的代码
  7. print('文件内容格式不正确。')
  8. finally: #确保文件能够关闭
  9. fp.close()
  10. except: #打开文件失败时执行的代码
  11. print('文件不存在')

异常类的实例和清除异常
每当有一一个异常被输出时,该异常类就会创建一个实例,此实例继承了异常类的所有属性。(最 重要的就是args属性)

  1. try:
  2. x = [1,2,3]
  3. print(x[4])
  4. except IndexError as err :
  5. print(err.args[0])
  6. list index out of range

IndexError: list index out of range
 

捕获多种异常处理结构

  1. >>>try:
  2. x = float(input('请输入整数:'))
  3. y = float(input('请输入除数:'))
  4. z = x / y
  5. except ZeroDivisionError:
  6. print('除数不能为零')
  7. except ValueError:
  8. print('被除数和除数应为数值类型')
  9. except NameError:
  10. print('变量不存在')
  11. else
  12. print(x,'/',y,'=',z)
  1. >>> a = 3
  2. >>> b = 5
  3. >>> assert a==b, 'a must be equal to b'
  4. AssertionError: a must be equal to b

跟踪查看异常

发生异常时Python能够记住引发的异常以及程序的当前状态,Python还维护着traceback(跟踪)对象,其中含有异常发生时与函数调用堆栈有关的信息,异常可能在一系列嵌套较深的函数调用中引发,程序调用每个函数时,Python会在“函数调用堆栈”的起始处插入函数名,一旦异常被引发 ,Python会搜索一个相应的异常处理程序。

如果当前函数中没有异常处理程序,当前函数会终止执行,Python会搜索当前函数的调用函数,并以此类推,直到发现匹配的异常处理程序,或者Python抵达主程序为止,这一查找合适的异常处理程序的过程就称为“堆栈辗转开解”(Stack Unwinding)。解释器一方面维护着与放置堆栈中的函数有关的信息,另一方面也维护着与已从堆栈中“辗转开解”的函数有关的信息。
 

  1. try
  2. block
  3. except:
  4. traceback.print_exc()

内置异常的协助模块

sys模块

sys模块中的exc_info()函数,可以取得目前正在处理的异常信息exc_info()函数会返回一个元组,这个元组包括三个元素。

  1. import sys
  2. try:
  3. 12/0
  4. except:
  5. info = sys.exc_info()
  6. exc_type = info[0]
  7. exc_value = info[1]
  8. exc_traceback = info[2]
  9. print(ecx_type,':',exc_value)

 

  1. import sys
  2. try:
  3. 12/0
  4. except :
  5. info=sys.exc_ info( )
  6. exc_ type=info[0]
  7. exc_ value = info[1]
  8. exc_ traceback = info[2]
  9. print(exc_ type, " :" ,exc_ value )
  10. <class ' ZeroDivisionError'> : division by zero

 traceback对象
使用sys模块的exc_ info() 函数返回值的第三个元素,会返回一个traceback对象。
traceback对象的接口函数可以捕捉、格式化,或是输出Python程序的堆栈追踪(traceback) 信息。

  1. import traceback
  2. try:
  3. 12/0
  4. except :
  5. traceback.print exc()
  6. Traceback (most recent call last) ;
  7. File "<ipython- input- 19- 71f6b5a77e1e>", line 4, in <module>
  8. 12/0
  9. ZeroDivisionError: division by zero

抛出异常

raise NameError ('抛出了一个异常')

  1. raise NameError( '这里是raise抛出的-个异常' )
  2. NameError
  3. Traceback (most recent cal1 last )
  4. <ipython- input- 20-e274246dfc1f> in <module>
  5. ----> 1 raise NameError( '这里是raise抛出的一个异常')
  6. NameError:这里是raise抛出的一 个异常

结束解释器的运行

用户可以利用输出SystemExit异常,来强迫结束解释器的运行

使用sys.exit()函数会输出一个SystemExit异常,sys.exit()会结束线程

  1. import sys
  2. try:
  3. sys.exit()
  4. except SystemExit:
  5. print('目前还不能结束解释器运行')
  6. #如果想正常结束解释器运行,最好利用OS模块的_exit()函数

 离开嵌套循环

使用raise语句离开嵌套循环

  1. class ExitLoop(Exception):
  2. pass
  3. try:
  4. i = 1
  5. while i < 10:
  6. for j in range(1, 10):
  7. print(i, j)
  8. if (i == 2) and (j == 2):
  9. raise(ExitLoop)
  10. i += 1
  11. except ExitLoop:
  12. print('当i = 2, j = 2时离开嵌套循环')

1 1
2 2
当i=2,j=2时离开循环嵌套
 

 用户自定义异常类

  1. class URLError(Exception):
  2. pass
  3. try:
  4. raise URLError(“URL ERROR”)
  5. except URLError as err:
  6. print(err.args[0])

 URL ERROR

 assert语句

原理:检查表达式的代码当表达式求值为真,一切正常;但若表达式求值为假,则暂停程序,打印消息,并在可行的情况下启动调试器。

  1. assert <测试码>[, 参数]
  2. #原理
  3. a = 10
  4. assert (a != 0),"Error happened, a = 0"
  5. print(a)

 如果a = 0会抛出 Error happened a = 0

__debug__内置变量

  1. if __debug__:
  2. if not (<测试码>):
  3. raise AssertionError [, 参数]
  1. import types
  2. def checkType(arg):
  3. if__debug__:
  4. if not (type(arg) == str):
  5. raise AssertionError("参数类型不是字符串")
  6. 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:参数类型不是字符串
 

断言与上下管理语句

  • 上下文管理(context manager)语句with可以自动管理资源,不论因为什么原因(哪怕是代码引发了异常)跳出with块,总能保证文件被正确关闭,并且可以在代码块执行完毕后自动还原进入该代码块时的现场,常用于文件操作、数据库连接、网络通信连接和多线程、多进程同步等场合。
  • with语句用于文件操作时的用法如下:

with open(filename, mode, encoding) as fp:

      # 通过文件对象fp操作文件的代码

tkinter简介

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创建新窗口

Tkinter开发基本步骤:

编写通用代码,例如数据库操作

搭建界面,放置组件,设置组件属性,可以借助PAGE

编写组件的事件处理代码

启动应用程序,启动消息主循环

用户登录界面

  1. import tkinter
  2. import tkinter.messagebox
  3. import os
  4. import os.path
  5. path = os.getenv('temp')
  6. filename = os.path.join(path, 'info.txt')
  7. #创建应用程序窗口
  8. root = tkinter.Tk()
  9. #定义窗口大小
  10. root['height'] = 140
  11. root['width'] = 200
  12. #在窗口上创建标签组件
  13. labelName = tkinter.Label(root,
  14. text='User Name:',
  15. justify=tkinter.RIGHT,
  16. anchor = 'e',
  17. width=80)
  18. #把组件放置到窗口上指定区域
  19. labelName.place(x=10, y=5, width=80, height=20)
  20. varName = tkinter.StringVar(root, value='')
  21. entryName = tkinter.Entry(root,
  22. width=80,
  23. textvariable=varName)
  24. entryName.place(x=100, y=5, width=80, height=20)
  25. labelPwd = tkinter.Label(root,
  26. text='User Pwd:',
  27. justify=tkinter.RIGHT,
  28. anchor = 'e',
  29. width=80)
  30. labelPwd.place(x=10, y=30, width=80, height=20)
  31. #创建密码文本框
  32. varPwd = tkinter.StringVar(root, value='')
  33. entryPwd = tkinter.Entry(root,
  34. show='*', #不管输入什么,都显示星号
  35. width=80,
  36. textvariable=varPwd)
  37. entryPwd.place(x=100, y=30, width=80, height=20)
  38. #尝试自动填写用户名和密码
  39. try:
  40. with open(filename) as fp:
  41. n, p = fp.read().strip().split(',')
  42. varName.set(n)
  43. varPwd.set(p)
  44. except:
  45. pass
  46. #记住我,复选框
  47. rememberMe = tkinter.IntVar(root, value=1)
  48. checkRemember = tkinter.Checkbutton(root,
  49. text='Remember me?',
  50. variable=rememberMe,
  51. onvalue=1,
  52. offvalue=0)
  53. checkRemember.place(x=30, y=70, width=120, height=20)
  54. #登录按钮事件处理函数
  55. def login():
  56. #获取用户名和密码
  57. name = entryName.get()
  58. pwd = entryPwd.get()
  59. if name=='admin' and pwd=='123456':
  60. tkinter.messagebox.showinfo(title='恭喜',
  61. message='登录成功!')
  62. if rememberMe.get() == 1:
  63. #把登录成功的信息写入临时文件
  64. with open(filename, 'w') as fp:
  65. fp.write(','.join((name,pwd)))
  66. else:
  67. try:
  68. #删除用于记录用户名和密码的临时文件
  69. os.remove(filename)
  70. except:
  71. pass
  72. else:
  73. tkinter.messagebox.showerror('警告',
  74. message='用户名或密码错误')
  75. #创建按钮组件,同时设置按钮事件处理函数
  76. buttonOk = tkinter.Button(root,
  77. text='Login', #设置按钮上显示的文本
  78. command=login) #设置按钮的单击事件处理函数
  79. buttonOk.place(x=30, y=100, width=50, height=20)
  80. #取消按钮的事件处理函数
  81. def cancel():
  82. #清空用户输入的用户名和密码
  83. varName.set('')
  84. varPwd.set('')
  85. buttonCancel = tkinter.Button(root,
  86. text='Cancel',
  87. command=cancel)
  88. buttonCancel.place(x=90, y=100, width=50, height=20)
  89. #启动消息循环
  90. root.mainloop()
  91. 12-2 tkinter单选钮、复选框、组合框、列表框综合运用案例。
  92. import tkinter
  93. import tkinter.messagebox
  94. import tkinter.ttk
  95. #创建tkinter应用程序
  96. root = tkinter.Tk()
  97. #设置窗口标题
  98. root.title('Selection widgets')
  99. #定义窗口大小
  100. root['height'] = 400
  101. root['width'] = 320
  102. #与姓名关联的变量
  103. varName = tkinter.StringVar()
  104. varName.set('')
  105. #创建标签,然后放到窗口上
  106. labelName = tkinter.Label(root,
  107. text='Name:',
  108. justify=tkinter.RIGHT,
  109. width=50)
  110. labelName.place(x=10, y=5, width=50, height=20)
  111. #创建文本框,同时设置关联的变量
  112. entryName = tkinter.Entry(root,
  113. width=120,
  114. textvariable=varName)
  115. entryName.place(x=70, y=5, width=120, height=20)
  116. labelGrade = tkinter.Label(root,
  117. text='Grade:',
  118. justify=tkinter.RIGHT, width=50)
  119. labelGrade.place(x=10, y=40, width=50, height=20)
  120. #模拟学生所在年级,字典键为年级,字典值为班级
  121. studentClasses = {'1':['1', '2', '3', '4'],
  122. '2':['1', '2'],
  123. '3':['1', '2', '3']}
  124. #学生年级组合框
  125. comboGrade = tkinter.ttk.Combobox(root,width=50,
  126. values=tuple(studentClasses.keys()))
  127. comboGrade.place(x=70, y=40, width=50, height=20)
  128. #事件处理函数
  129. def comboChange(event):
  130. grade = comboGrade.get()
  131. if grade:
  132. #动态改变组合框可选项
  133. comboClass["values"] = studentClasses.get(grade)
  134. else:
  135. comboClass.set([])
  136. #绑定组合框事件处理函数
  137. comboGrade.bind('<<ComboboxSelected>>', comboChange)
  138. labelClass = tkinter.Label(root,
  139. text='Class:',
  140. justify=tkinter.RIGHT, width=50)
  141. labelClass.place(x=130, y=40, width=50, height=20)
  142. #学生班级组合框
  143. comboClass = tkinter.ttk.Combobox(root, width=50)
  144. comboClass.place(x=190, y=40, width=50, height=20)
  145. labelSex = tkinter.Label(root,
  146. text='Sex:',
  147. justify=tkinter.RIGHT, width=50)
  148. labelSex.place(x=10, y=70, width=50, height=20)
  149. #与性别关联的变量,1:男;0:女,默认为男
  150. sex = tkinter.IntVar()
  151. sex.set(1)
  152. #单选钮,男
  153. radioMan = tkinter.Radiobutton(root,
  154. variable=sex,
  155. value=1,
  156. text='Man')
  157. radioMan.place(x=70, y=70, width=50, height=20)
  158. #单选钮,女
  159. radioWoman = tkinter.Radiobutton(root,
  160. variable=sex,
  161. value=0,
  162. text='Woman')
  163. radioWoman.place(x=130, y=70, width=70, height=20)
  164. #与是否班长关联的变量,默认当前学生不是班长
  165. monitor = tkinter.IntVar()
  166. monitor.set(0)
  167. #复选框,选中时变量值为1,未选中时变量值为0
  168. checkMonitor = tkinter.Checkbutton(root,
  169. text='Is Monitor?',
  170. variable=monitor,
  171. onvalue=1,
  172. offvalue=0)
  173. checkMonitor.place(x=20, y=100, width=100, height=20)
  174. #添加按钮单击事件处理函数
  175. def addInformation():
  176. result = 'Name:' + entryName.get()
  177. result = result + ';Grade:' + comboGrade.get()
  178. result = result + ';Class:' + comboClass.get()
  179. result = result + ';Sex:'\
  180. + ('Man' if sex.get() else 'Woman')
  181. result = result + ';Monitor:'\
  182. + ('Yes' if monitor.get() else 'No')
  183. #把信息插入到列表框组件中
  184. listboxStudents.insert(0, result)
  185. buttonAdd = tkinter.Button(root,
  186. text='Add',
  187. width=40,
  188. command=addInformation)
  189. buttonAdd.place(x=130, y=100, width=40, height=20)
  190. #删除按钮的事件处理函数
  191. def deleteSelection():
  192. selection = listboxStudents.curselection()
  193. if not selection:
  194. tkinter.messagebox.showinfo(title='Information',
  195. message='No Selection')
  196. else:
  197. listboxStudents.delete(selection)
  198. buttonDelete = tkinter.Button(root,
  199. text='DeleteSelection',
  200. width=100,
  201. command=deleteSelection)
  202. buttonDelete.place(x=180, y=100, width=100, height=20)
  203. #创建列表框组件
  204. listboxStudents = tkinter.Listbox(root, width=300)
  205. listboxStudents.place(x=10, y=130, width=300, height=200)
  206. #启动消息循环
  207. root.mainloop()

  1. import os
  2. import tkinter
  3. import tkinter.simpledialog
  4. import tkinter.colorchooser
  5. import tkinter.filedialog
  6. #需要执行pip install pillow安装扩展库
  7. from PIL import ImageGrab
  8. root = tkinter.Tk()
  9. root.title('My Paint----by Dong Fuguo')
  10. root['width'] = 800
  11. root['height'] = 600
  12. #控制是否允许画图的变量,1:允许,0:不允许
  13. canDraw = tkinter.IntVar(value=0)
  14. what = tkinter.IntVar(value=1)
  15. #记录鼠标位置的变量
  16. X = tkinter.IntVar(value=0)
  17. Y = tkinter.IntVar(value=0)
  18. #前景色、背景色
  19. foreColor = '#000000'
  20. backColor = '#FFFFFF'
  21. #创建画布
  22. image = tkinter.PhotoImage()
  23. canvas = tkinter.Canvas(root,
  24. bg='white',
  25. width=800, height=600)
  26. canvas.create_image(800, 600, image=image)
  27. #鼠标左键单击,允许画图,并记录当前鼠标位置
  28. def onLeftButtonDown(event):
  29. canDraw.set(1)
  30. X.set(event.x)
  31. Y.set(event.y)
  32. if what.get()==4:
  33. canvas.create_text(event.x, event.y, text=text)
  34. canvas.bind('<Button-1>', onLeftButtonDown)
  35. #记录最后绘制图形的id
  36. lastDraw = 0
  37. #按住鼠标左键移动,画图
  38. def onLeftButtonMove(event):
  39. global lastDraw
  40. if canDraw.get()==0:
  41. return
  42. if what.get()==1:
  43. #使用当前选择的前景色绘制曲线
  44. canvas.create_line(X.get(), Y.get(), event.x,
  45. event.y, fill=foreColor)
  46. X.set(event.x)
  47. Y.set(event.y)
  48. elif what.get()==2:
  49. #绘制直线,先删除刚刚画过的直线,再画一条新的直线
  50. try:
  51. canvas.delete(lastDraw)
  52. except Exception as e:
  53. pass
  54. lastDraw = canvas.create_line(X.get(), Y.get(),
  55. event.x, event.y,
  56. fill=foreColor)
  57. elif what.get()==3:
  58. #绘制矩形,先删除刚刚画过的矩形,再画一个新的矩形
  59. try:
  60. canvas.delete(lastDraw)
  61. except Exception as e:
  62. pass
  63. lastDraw = canvas.create_rectangle(X.get(), Y.get(),
  64. event.x, event.y,
  65. fill=backColor,
  66. outline=foreColor)
  67. elif what.get()==5:
  68. #橡皮,使用背景色填充10*10的矩形区域
  69. canvas.create_rectangle(event.x-5, event.y-5,
  70. event.x+5, event.y+5,
  71. outline=backColor, fill=backColor)
  72. canvas.bind('<B1-Motion>', onLeftButtonMove)
  73. #鼠标左键抬起,不允许再画图了
  74. def onLeftButtonUp(event):
  75. if what.get()==2:
  76. #绘制直线
  77. canvas.create_line(X.get(),
  78. Y.get(),
  79. event.x,
  80. event.y,
  81. fill=foreColor)
  82. elif what.get()==3:
  83. #绘制矩形
  84. canvas.create_rectangle(X.get(),
  85. Y.get(),
  86. event.x,
  87. event.y,
  88. fill=backColor,
  89. outline=foreColor)
  90. canDraw.set(0)
  91. global lastDraw
  92. #防止切换图形时误删上次绘制的图形
  93. lastDraw = 0
  94. canvas.bind('<ButtonRelease-1>', onLeftButtonUp)
  95. #创建菜单
  96. menu = tkinter.Menu(root, tearoff=0)
  97. #打开图像文件
  98. def Open():
  99. filename = tkinter.filedialog.askopenfilename(title='Open Image',
  100. filetypes=[('image', '*.jpg *.png *.gif')])
  101. if filename:
  102. global image
  103. image = tkinter.PhotoImage(file=filename)
  104. canvas.create_image(80, 80, image=image)
  105. menu.add_command(label='Open', command=Open)
  106. def Save():
  107. #获取客户区域位置和尺寸,并截图保存
  108. left = int(root.winfo_rootx())
  109. top = int(root.winfo_rooty())
  110. width = root.winfo_width()
  111. height = root.winfo_height()
  112. im = ImageGrab.grab((left,top,left+width,top+height))
  113. #保存绘制的图片
  114. filename = tkinter.filedialog.asksaveasfilename(title='保存图片',
  115. filetypes=[('图片文件','*.png')])
  116. if not filename:
  117. return
  118. if not filename.endswith('.png'):
  119. filename = filename+'.png'
  120. im.save(filename)
  121. menu.add_command(label='Save', command=Save)
  122. #添加菜单,清除,遍历画布上的所有图像,逐个删除
  123. def Clear():
  124. for item in canvas.find_all():
  125. canvas.delete(item)
  126. menu.add_command(label='Clear', command=Clear)
  127. #添加分割线
  128. menu.add_separator()
  129. #创建子菜单,用来选择绘图类型
  130. menuType = tkinter.Menu(menu, tearoff=0)
  131. def drawCurve():
  132. what.set(1)
  133. menuType.add_command(label='Curve', command=drawCurve)
  134. def drawLine():
  135. what.set(2)
  136. menuType.add_command(label='Line', command=drawLine)
  137. def drawRectangle():
  138. what.set(3)
  139. menuType.add_command(label='Rectangle', command=drawRectangle)
  140. def drawText():
  141. global text
  142. text = tkinter.simpledialog.askstring(title='Input what you want to draw', prompt='')
  143. what.set(4)
  144. menuType.add_command(label='Text', command=drawText)
  145. menuType.add_separator()
  146. #选择前景色
  147. def chooseForeColor():
  148. global foreColor
  149. foreColor = tkinter.colorchooser.askcolor()[1]
  150. menuType.add_command(label='Choose Foreground Color',
  151. command=chooseForeColor)
  152. #选择背景色
  153. def chooseBackColor():
  154. global backColor
  155. backColor = tkinter.colorchooser.askcolor()[1]
  156. menuType.add_command(label='Choose Background Color',
  157. command=chooseBackColor)
  158. #橡皮
  159. def onErase():
  1. import tkinter
  2. import tkinter.messagebox
  3. import random
  4. import threading
  5. import itertools
  6. import time
  7. root = tkinter.Tk()
  8. # 窗口标题
  9. root.title('随机提问')
  10. # 窗口初始大小和位置
  11. root.geometry('260x180+400+300')
  12. # 不允许改变窗口大小
  13. root.resizable(False, False)
  14. # 关闭程序时执行的函数代码,停止滚动显示学生名单
  15. def closeWindow():
  16. # 标记flat变量为False,停止滚动
  17. root.flag = False
  18. # 暂停0.1秒,等待用于滚动名单的子线程结束
  19. time.sleep(0.1)
  20. # 销毁窗口,关闭程序
  21. root.destroy()
  22. # 绑定消息处理函数,当窗口关闭时会触发'WM_DELETE_WINDOW'消息
  23. root.protocol('WM_DELETE_WINDOW', closeWindow)
  24. # 模拟学生名单,这些学生姓名在窗口上滚动
  25. students = ['张三', '李四', '王五', '赵六', '周七', '钱八']
  26. # 变量,用来控制是否滚动显示学生名单,默认启动时不滚动
  27. root.flag = False
  28. # 用户滚动名单的线程函数
  29. def switch():
  30. root.flag = True
  31. # 随机打乱学生名单
  32. t = students[:]
  33. random.shuffle(t)
  34. # 创建cycle对象,用于实现无限重复的滚动
  35. t = itertools.cycle(t)
  36. # 一直滚动,直到flag的值为False
  37. while root.flag:
  38. # 滚动显示
  39. # 把第二个人名移动到第一个
  40. # 把第三个人名移动到第二个
  41. # 获取一个新的人名显示为第三个
  42. lbFirst['text'] = lbSecond['text']
  43. lbSecond['text'] = lbThird['text']
  44. lbThird['text'] = next(t)
  45. # 数字可以修改,控制滚动速度
  46. time.sleep(0.1)
  47. def btnStartClick():
  48. # 每次单击“开始”按钮创建并启动新线程
  49. t = threading.Thread(target=switch)
  50. t.start()
  51. # 把“开始”按钮禁用,避免重复响应单击操作
  52. btnStart['state'] = 'disabled'
  53. # 启用“停”按钮
  54. btnStop['state'] = 'normal'
  55. btnStart = tkinter.Button(root,
  56. text='开始',
  57. command=btnStartClick)
  58. btnStart.place(x=30, y=10, width=80, height=20)
  59. def btnStopClick():
  60. # 单击“停”按钮结束滚动显示
  61. root.flag = False
  62. # 等待0.3秒,彻底停止滚动之后再获取中奖的人名
  63. time.sleep(0.3)
  64. tkinter.messagebox.showinfo('恭喜',
  65. '本次中奖:'+lbSecond['text'])
  66. # 启用“开始”按钮,禁用“停”按钮
  67. btnStart['state'] = 'normal'
  68. btnStop['state'] = 'disabled'
  69. btnStop = tkinter.Button(root,
  70. text='停',
  71. command=btnStopClick)
  72. # 程序启动时,“停”按钮初始设置为禁用
  73. btnStop['state'] = 'disabled'
  74. btnStop.place(x=150, y=10, width=80, height=20)
  75. # 用来滚动显示学生名单的3个Label组件
  76. # 可以根据需要进行添加,但要修改上面的线程函数代码
  77. lbFirst = tkinter.Label(root, text='')
  78. lbFirst.place(x=80, y=60, width=100, height=20)
  79. # 红色Label组件,表示中奖名单
  80. lbSecond = tkinter.Label(root, text='')
  81. lbSecond['fg'] = 'red'
  82. lbSecond.place(x=80, y=90, width=100, height=20)
  83. lbThird = tkinter.Label(root, text='')
  84. lbThird.place(x=80, y=120, width=100, height=20)
  85. # 启动消息主循环,启动应用程序
  86. root.mainloop()
  87. 12-7 使用tkinter实现计算器程序
  88. import re
  89. import tkinter
  90. import tkinter.messagebox
  91. root = tkinter.Tk()
  92. # 设置窗口大小和位置
  93. root.geometry('300x270+400+100')
  94. # 不允许改变窗口大小
  95. root.resizable(False, False)
  96. # 设置窗口标题
  97. root.title('简易计算器-董付国')
  98. # 字符串变量
  99. contentVar = tkinter.StringVar(root, '')
  100. # 用来显示表达式的文本框,设置关联变量
  101. contentEntry = tkinter.Entry(root, textvariable=contentVar)
  102. # 设置为只读,只能通过按钮来输入要计算的表达式
  103. contentEntry['state'] = 'readonly'
  104. contentEntry.place(x=10, y=10, width=280, height=20)
  105. # 按钮通用代码,参数btn表示按钮的是哪个按钮
  106. def buttonClick(btn):
  107. content = contentVar.get()
  108. # 如果已有内容是以小数点开头的,前面加0
  109. if content.startswith('.'):
  110. content = '0' + content
  111. # 根据不同按钮做出相应的处理
  112. if btn in '0123456789':
  113. # 普通数字按钮,直接连接到表达式最后
  114. content += btn
  115. elif btn == '.':
  116. # 如果最后一个运算数中已经有小数点,就提示错误
  117. lastPart = re.split(r'\+|-|\*|/]', content)[-1]
  118. if '.' in lastPart:
  119. tkinter.messagebox.showerror('错误', '小数点太多了')
  120. return
  121. else:
  122. # 最后一个运算数中没有小数点,把小数点连接到最后
  123. content += btn
  124. elif btn == 'C':
  125. # 清除整个表达式
  126. content = ''
  127. elif btn == '=':
  128. # 按下等于号按钮,计算结果
  129. try:
  130. # 尝试对输入的表达式求值
  131. content = str(eval(content))
  132. except:
  133. tkinter.messagebox.showerror('错误', '表达式错误')
  134. return
  135. elif btn in operators:
  136. # 按下运算符按钮,表达式中不允许有连续的运算符
  137. if content.endswith(operators):
  138. tkinter.messagebox.showerror('错误',
  139. '不允许存在连续运算符')
  140. return
  141. content += btn
  142. elif btn == 'Sqrt':
  143. # 求平方根
  144. # 切分出整数部分和小数部分
  145. n = content.split('.')
  146. # 要求小数点前后都是数字,如果表达式中含有运算符,不符合要求
  147. if all(map(lambda x: x.isdigit(), n)):
  148. content = eval(content) ** 0.5
  149. else:
  150. tkinter.messagebox.showerror('错误', '表达式错误')
  151. return
  152. # 显示计算结果
  153. contentVar.set(content)
  154. # 放置清除按钮和等号按钮
  155. btnClear = tkinter.Button(root,
  156. text='Clear',
  157. command=lambda:buttonClick('C'))
  158. btnClear.place(x=40, y=40, width=80, height=20)
  159. btnCompute = tkinter.Button(root,
  160. text='=',
  161. command=lambda:buttonClick('='))
  162. btnCompute.place(x=170, y=40, width=80, height=20)
  163. #放置10个数字、小数点和计算平方根的按钮
  164. digits = list('0123456789.') + ['Sqrt']
  165. index = 0
  166. for row in range(4):
  167. for col in range(3):
  168. d = digits[index]
  169. index += 1
  170. btnDigit = tkinter.Button(root,
  171. # 按钮上显示的内容
  172. text=d,
  173. # 按下按钮时执行的函数
  174. command=lambda x=d:buttonClick(x))
  175. # 把按钮放置到窗口上
  176. btnDigit.place(x=20+col*70,
  177. y=80+row*50,
  178. width=50,
  179. height=20)
  180. # 放置运算符按钮
  181. operators = ('+', '-', '*', '/', '**', '//')
  182. for index, operator in enumerate(operators):
  183. btnOperator = tkinter.Button(root,
  184. text=operator,
  185. command=lambda x=operator:buttonClick(x))
  186. btnOperator.place(x=230, y=80+index*30, width=50, height=20)
  187. # 启动消息主循环,启动应用程序
  188. root.mainloop()
  189. 12-8 使用tkinter实现定时自动关闭的窗口
  190. import time
  191. import tkinter
  192. import threading
  193. # 创建应用程序窗口,设置标题和大小
  194. root = tkinter.Tk()
  195. root.title('倒计时自动关闭的窗口')
  196. root['width'] = 400
  197. root['height'] = 300
  198. # 不允许改变窗口大小
  199. root.resizable(False, False)
  200. # 创建Text组件,放置一些文字
  201. richText = tkinter.Text(root, width=380)
  202. richText.place(x=10, y=10, width=380, height=230)
  203. # 连续插入5行内容
  204. # '0.0'表示插入位置,第0行第0列
  205. # 如果想让插入的内容占一行,需要在字符串最后有换行符
  206. for i in range(5):
  207. # f字符串语法,会把{i}替换为i的当前实际值
  208. richText.insert(f'{i}.0',
  209. '假设阅读这些文字需要10秒钟时间\n')
  210. # 显示倒计时的Label
  211. lbTime = tkinter.Label(root, fg='red', anchor='w')
  212. lbTime.place(x=10, y=250, width=150)
  213. def autoClose():
  214. # 倒计时10秒钟
  215. for i in range(10):
  216. # f字符串语法,对{}中的表达式进行计算并替换
  217. lbTime['text'] = f'距离窗口关闭还有{10-i}秒'
  218. # 每秒钟修改一次提示信息
  219. time.sleep(1)
  220. root.destroy()
  221. # 创建并启动线程
  222. t = threading.Thread(target=autoClose)
  223. t.start()
  224. # 启动消息主循环,启动应用程序
  225. root.mainloop()
  226. import time
  227. import tkinter
  228. import threading
  229. # 创建应用程序窗口,设置标题和大小
  230. root = tkinter.Tk()
  231. root.title('倒计时自动关闭的窗口')
  232. root['width'] = 400
  233. root['height'] = 300
  234. # 不允许改变窗口大小
  235. root.resizable(False, False)
  236. # 创建Text组件,放置一些文字
  237. richText = tkinter.Text(root, width=380)
  238. richText.place(x=10, y=10, width=380, height=230)
  239. # 连续插入5行内容
  240. # '0.0'表示插入位置,第0行第0列
  241. # 如果想让插入的内容占一行,需要在字符串最后有换行符
  242. for i in range(5):
  243. # f字符串语法,会把{i}替换为i的当前实际值
  244. richText.insert(f'{i}.0',
  245. '假设阅读这些文字需要10秒钟时间\n')
  246. # 显示倒计时的Label
  247. lbTime = tkinter.Label(root, fg='red', anchor='w')
  248. lbTime.place(x=10, y=250, width=150)
  249. def autoClose():
  250. # 倒计时10秒钟
  251. for i in range(10):
  252. # f字符串语法,对{}中的表达式进行计算并替换
  253. lbTime['text'] = f'距离窗口关闭还有{10-i}秒'
  254. # 每秒钟修改一次提示信息
  255. time.sleep(1)
  256. root.destroy()
  257. # 创建并启动线程
  258. t = threading.Thread(target=autoClose)
  259. t.start()
  260. # 启动消息主循环,启动应用程序
  261. root.mainloop()

日志

 logging库日志级别
 

级别                级别数值                使用时机
DEBUG               10                      详细信息,常用于调试。
INFO                    20                      程序正常运行过程中产“生的一些信息。
WARNING            30                      警告用户,虽然程序还在正常工作,但有可能发生错误。
ERROR                 40                     由于更严重的问题,程序已不能执行一些功能了。
CRITICAL               50                    严重错误,程序已不能继续运行。

  1. import logging
  2. #print("This is a 10g. text")
  3. logging. debug("This is debug log")
  4. logging.info("This is info Log")
  5. logging.warning("This is warning log")
  6. logging.error("This is error Log")
  7. logging.critical("This is critical log")
  1. WARNING: root:This is wa rning log
  2. ERROR: root:This is error Log
  3. CRITICAL : root:This is critical Log
  4. Process finished with exit code 0
  1. import logging
  2. #使用baseConfig( )来指定日志输出级别
  3. logging.basicConfig( leve1= logging. DEBUG)
  4. print("This is a log text")
  5. logging.debug("This is debug log" )
  6. logging.info("This is info log")
  7. logging.warning("This is warning log")
  8. logging.error("This is error log")
  9. logging.critical(This is critical log")

输出代码: 

  1. DEBUG: root:This is debug log
  2. INFO: root:This is info log
  3. WARNING: root:This is warning log
  4. ERROR: root:This is error log
  5. CRITICAL: root:This is critical log
  6. This is a log text

logging . basicConfig( filename='demo,Log', fi lemode= 'w's leve (= Logging . DEBUG

新生成一个叫demo.log的文件 每次记录日志都会重新写入 不依次追加 默认是追加

  1. loggingbasicConfig(format="%(message)s", level=logging.DEBUG)
  2. name = “张三"
  3. age = 18
  4. logging.debug("姓名%s, 年龄%d", name, age )

 可以只输出信息 

  1. logging.basicConfig(format="%(asctime)s|%(LeveLnames|%(filename)s:% (lineno)s|% (message)s
  2. ", leve L= logging. DEBUG)

 2021-09-16 11:07:52, 161 DEBUG|2.2py:10|姓名张三,年龄18

日志logging


高级应用,四个组件:


Loggers:记录器
Handlers:处理器
Filters:过滤器
Formatters:格式化器

  1. import logging
  2. import logging.config
  3. #配置文件的方式来处理日志
  4. logging.config.fileConfig('logging.config')
  5. logger = logging.getLogger('applog')
  6. #打印日志
  7. logger.debug("This is a debug log")
  8. logger.info("This is a info log")
  9. logger.warning("This is a warning log")
  10. logger.error("This is a error log")
  11. logger.critical("This is a critical log")

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/710845
推荐阅读