文章目录

  • 2 print
  • 3 数学
  • 4 自变量
  • 5 while循环
  • 6 for循环
  • 7 if 条件
  • 8 if else条件
  • 9 if elif else
  • 10 def 函数
  • 11 函数、参数
  • 12 函数默认参数
  • 13 全局&局部变量,global&local
  • 15 读写文件
    • 重写
    • 附加
  • 18 class类
  • 19 类的init功能
  • 20 input输入
  • 21 元组&列表
    • 22 列表 list
      • 增加(append)
      • 插入(insert)
      • 移除(remove)
      • 索引
        • 索引位置
        • 索引值
      • 计数(count)
      • 排序(sort)
  • 23 多维列表
    • 排序(sort)
  • 24 字典
  • 25 import
  • 26 自己的模块
  • 27 continue&break
  • 28 错误处理try....except...else
  • 29 zip lambda map
  • 30 浅复制&深复制(copy&deepcopy)
  • 31 Threading 多线程
    • 1 什么是多线程
    • 2 增加线程 add thread
    • 3 join
    • 4 Queue
    • 5 不一定有效率 GIL
    • 6 锁 lock
  • 32 Multiprocessing 让你的多核计算机发挥真正潜力
    • 1 什么是多进程
    • 2 创建进程
    • 3 queue
    • 4 效率对比 multithreading和multiprocessing
    • 5 进程池 pool
    • 6 共享内存 shared memory
    • 7 lock锁
  • 33 Tkinter 做简单的窗口视窗 Python GUI
    • 1 Tkinter是什么
    • 2 Label & Button标签和按钮
    • 3 Entry & Text输入,文本框
    • 4 Listbox列表部件
    • 5 Radiobutton选择按钮
    • 6 Scale尺度
    • 7 Checkbutton勾选项
    • 8 Canvas 画布
    • 9 Menubar 菜单
    • 10 Frame框架
    • 11 messagebox弹窗
    • 12 pack grid place放置位置
    • 13例子1登录窗口
    • 14例子1登录窗口
    • 15例子1登录窗口

2 print

print(1)

字符串 print(‘’) print(“”)

print('I\‘m yan’) 斜杠后加个单引号就不会被判为字符串的结束单引号

括号内绿色表示字符串,黑色表示命令

a = 2
b = a*3
print(a,b)
>>> print(1)
1
>>> print('We are')
We are
>>> print("we are going")
we are going
>>> print('I\'m yan')
I'm yan
>>> print('apple'+'car')
applecar
>>> print('apple'+4)
Traceback (most recent call last):File "<pyshell#11>", line 1, in <module>print('apple'+4)
TypeError: can only concatenate str (not "int") to str
>>> print('apple'+'4')
apple4
>>> print('apple'+str(4))
apple4
>>> print(1+2)
3
>>> print('1+2')
1+2
>>> print(int('1')+2)
3
>>> print('1.2'+2)
Traceback (most recent call last):File "<pyshell#17>", line 1, in <module>print('1.2'+2)
TypeError: can only concatenate str (not "int") to str
>>> print(float('2.3')+2)
4.3

3 数学

加+ 减- 乘* 除/ 幂** 取余数% 取整//
>>> 1+1
2
>>> 1-1
0
>>> 2*2
4
>>> 3**2
9
>>> 2**4
16
>>> 8%2
0
>>> 8%3
2
>>> 7/3
2.3333333333333335
>>> 9//4
2
>>> 10//3
3
>>> 10/2
5.0

4 自变量

File-New file

a = 1
b = 2
c = 3
print(a,b,c)

或写成

a,b,c=1,2,3
print(a,b,c)

自变量运算

a=2
b=a*3
print(a,b)

运行时Run-Run Module

5 while循环

condition = 1
while condition < 10:print (condition)condition = condition + 1

持续循环时,用ctrl+c跳出

while True:print("I'm True")

6 for循环

在for循环之内的语句是在四个空格后写,如下面的print和inner语句 ,后面的outer语句在for之外。

另外 i 在列表中用for ,i会自动加1?

examp1e_1ist = [1,2,3,4,5,6,7,12,254,564,23,4,5,6]for i in examp1e_1ist:print(i)print (' inner of for')print (' outrt of for')

运行结果:

1inner of for
2inner of for
3inner of for
4inner of for
5inner of for
6inner of for
7inner of for
12inner of for
254inner of for
564inner of for
23inner of for
4inner of for
5inner of for
6inner of foroutrt of for

选中for中包含的语句,按住CTRL+[ 或 CTRL+] 可以讲语句整体左右移动。

range含头不含尾(4,10)输出的是4-9

for i in range(4,10):print(i)

运行结果:

4
5
6
7
8
9

range(a,b,step) 表示从a到b,并且步进为step

for i in range(4,10,4):print(i)

运行结果:

4
8

打出左括号后显示黄色使用介绍框

7 if 条件

大小可以做连续的判断,而不是像C语言先判断x<y为1后再判断1>z.

而是判断 x<y,y>z是否同时成立。

x=1
y = 2
z= 1if x < y >z:print ('yes')

运行结果为yes。

连续判断不正确则不输出yes

大于等于>= 小于等于<= 等于判断== 不等于!=

8 if else条件

if else 的位置相同,并且后面都有冒号。

x=5
y= 3
z= 9if x <y :print('x < y')
else:print('x >= y')

运行结果:

x >= y

9 if elif else

满足if的第一个条件后就会跳出if elif else 语句

x=5
y =3
z= 9if x > 8:print('x >8')
elif x <=8:print ('x <= 8')
elif x <6:print('x < 6')
print( 'finish ifelse' )

运行结果:

x <= 8
finish ifelse

10 def 函数

定义一个函数名字叫function或其他,再在命令行中使用函数名进行调用。

或者直接在脚本中定了了函数后调用,直接运行。

def function():print ('this is a function')a =1 +2print(a)function()

11 函数、参数

def fun(a, b) :c = a*bprint(' c=a*b=', c)
>>> fun(4,7)c=a*b= 28
>>> fun(b=6,a=3)c=a*b= 18

输出替换,转成字符串,此时的+号表示将两字符串连接

def multip1y(a,b):c = a*bprint(str(c)+"="+str(a) +"*"+str(b))
>>> multip1y(6,8)
48=6*8

在Python中,f字符串(或称为格式化字符串)是一种方便的字符串格式化方式,可以将变量的值插入到字符串中。在f字符串中,可以使用花括号{}来包含变量名,这些变量名将在运行时被替换为它们的值。

def multiply(a,b):c=a*bprint(f'{c}={a}*{b}')
>>> multiply(3,6)
18=3*6

12 函数默认参数

通过函数赋值

def sale_car (price,color,brand,is_second_hand) :print (' price:',price,'co1or:',color,'brand:',brand,'is_second_hand:',is_second_hand)sale_car (10203,'red', 'carry', True)
 price: 10203 co1or: red brand: carry is_second_hand: True

1中是默认参数赋值,2中是需要将函数内的内容修改,可以观察到输出被修改为blue

需要定义的值不能在默认定义的值后面,否则会报错。如下需要定义品牌,放在了以及定义好的颜色后面,会报错。

改变位置后运行

13 全局&局部变量,global&local

APPLE为全局变量,a为局部变量,所有打印局部时报错

APPLE=100def fun():a= 10return a+100print (APPLE)
print(a)
100
Traceback (most recent call last):File "C:/Users/Desktop/python_exercise/pyyy.py", line 8, in <module>print(a)
NameError: name 'a' is not defined

打印函数返回值

APPLE=100def fun():a= APPLEreturn a+100print (APPLE)
print(fun())
100
200

按理全局变量放外边,如果一定想把全局放在函数内则使用global。

未运行之前的a为none,运行了fun函数之后a变为20。(此种情况一定记得在最前面对a赋值)

a =None
def fun():global aa= 20return a+100print('a past is', a)
print(fun())
print('a now is', a)
a past is None
120
a now is 20

如果没有global a语句时,运行后a仍然为none

a =None
def fun():a= 20return a+100print('a past is', a)
print(fun())
print('a now is', a)
a past is None
120
a now is None

15 读写文件

open()中的文件名没有,则会生成一个对应名字的文件,w表示write写操作。

写的内容在第一行表示了(text),其中的\n表示换行

写了之后必须记得要关上文档,所以close

text = "This is my first text.\nThis is next line.\nThis is last 1ine."
my_py_fi1e=open(' my_py_file.txt','w')
my_py_fi1e. write(text)
my_py_fi1e.close()

运行后会在此程序的存储位置中生成一个txt,其内容是我们写入的内容。

重写

如果直接写 add a new line 时会将原来的原件清空后写新内容

text = "This is my first text.\nThis is next line.\nThis is last 1ine."
my_py_fi1e=open(' my_py_file.txt','w')
my_py_fi1e. write('add a new line')
my_py_fi1e.close()

如下

附加

如果我们将open后的写改为附加(w改为a a表示append)

text = "This is my first text.\nThis is next line.\nThis is last 1ine."
append_txt='\nadd a new line'
my_py_fi1e=open(' my_py_file.txt','a')
my_py_fi1e. write(append_txt)
my_py_fi1e.close()

此时txt内容变为

my_fi1e = open(' my_py_file.txt','r')
counter = my_fi1e.read()
print(counter)
This is my first text.
This is next line.
This is last 1ine.
add a new line

readline 表示读行,一行一行的读

my_fi1e=open(' my_py_file.txt','r')
counter = my_fi1e.readline()
second_read =my_fi1e.readline()
print (counter, second_read)
This is my first text.This is next line.

readlines 表示全部读取

my_fi1e=open(' my_py_file.txt','r')
counter = my_fi1e.readlines()
print (counter)
['This is my first text.\n', 'This is next line.\n', 'This is last 1ine.\n', 'add a new line']

18 class类

class类,一般类是以首字母大写命名。

class Calculator:name = 'Good ca1cu1ator'price = 18def add(x, y):result =x+yprint (result)def minus (x,y):result =x-yprint (result)def times(x,y):result =x*yprint (result)def divide(x, y) :result = x/yprint (result)
>>> cal = Calculator
>>> cal.name
'Good ca1cu1ator'
>>> cal.price
18
>>> cal.minus(9,14)
-5
>>> cal.times(4,8)
32
>>> cal.divide(7,2)
3.5

19 类的init功能

注意此处的初始化左右是两个短线 ——init——,同时括号中要用self

class Calculator:def __init__(self,name,price,hight=20,width=16,weight=18):self.n = nameself.p = priceself.h = hightself.wi = widthself.we = weightdef add(self,x,y):result = x + yprint(result)def minus(self,x,y):result = x-yprint(result) def times(self,x,y):result = x*yprint(result)def divide(self,x,y):result = x/yprint(result)
>>> c=Calculator('yuan',1)
>>> c.n
'yuan'
>>> c.p
1
>>> c.h
20
>>> c.we
18
>>> c.wi
16

使用类是一定记得加上self,否则会出现报错

如下初始化的时候用到了self.add 如果下面定义的函数中括号里没有self会出现报错,这样在初始就会计算一个加法。

同样不加self在命令行中使用c.we等也会报错。

20 input输入

input返回的是一个字符串

a_input = input (' P1ease give a number : ')
print ('This input number is',a_input)

input的字符串判断要通过用字符串表示的str(1)或‘2’来判断。

a_input = input (' P1ease give a number: ')
if a_input == str(1):print ('This is a good one')
elif a_input == '2':print (' see you')
else :print ('Good luck')

或者把input的数据转换为int类型再做判断

21 元组&列表

tuple元组 表示为(1,2,3,4,7)或 1,2,5,7,8 。即放在小括号内或无括号。

list列表[12,4,3,5,6]

a_tup1e =(2,5,6,7,4)
b_tup1e=5,6,3,2a_list =[3,6,76,3,6]for x in a_list:print(x)

运行结果:

3
6
76
3
6

len 表示长度,如此处的len(a_tuple)为5,range(5)就是0-4,此时就是输出a_tuple的0-4,就是全部数字。

虽然元组和列表的表示不一样,但是在print中都是用的中括号[]才不会报错。如果用小括号()会出现报错。

22 列表 list

增加(append)

在列表后面增加用到append

插入(insert)

在列表指定位置插入insert

此处表示在0,1,2的2位置上插入99

移除(remove)

remove表示移除值,而不是索引位,比如此处remove(5)表示的是移除掉列表中的第一个5,注意只会移除第一个5。

如下联系两次移除5

索引

索引位置

索引时可以用-1,-2等表示索引最后一位,倒数位等。

索引a[0:3]实际上索引的是0,1,2位(含头不含尾)。a[:3]表示从最前到2的位置,如下

a[-3:]也能够表示最后的第三位

索引值

索引值9的位置,用index可以知道9在第4位(01234)

计数(count)

列表a,计数5的数量,为3个

排序(sort)

sort会使得列表从小到大排序,并且排序后会覆盖掉原来的a,所以此时仍然是print(a),而不是print(a.sort())

如果要从大到小排序,则使用sort(reverse=Ture)

23 多维列表

排序(sort)

sort会使得列表从小到大排序,并且排序后会覆盖掉原来的a,所以此时仍然是print(a),而不是print(a.sort())

如果要从大到小排序,则使用sort(reverse=Ture)

a=[1,5,3,5,9,5,2]
multi_dim_a=[[1,2,3],[4,5,6],[7,8,9]]
print('a[3]=',a[3])
print('multi_dim_a[2][1]=',multi_dim_a[2][1])

运行结果(多维中[2][1]表示012,01的2和1):

a[3]= 5
multi_dim_a[2][1]= 8

24 字典

注意打印时的索引仍然用的[ ],而不是{ },增加字典内容也是[ ]。

d={'apple':3,'pear':7,'orange':9}   #字典
print('d=',d)
print('d[orange]=',d['orange'])del d['pear']   #删除pear
print('deleted prar d=',d)d['b'] = 20 #增加字典内容
d['pig'] = 100
d[1]= 12
print('add d=',d)

运行结果:

d= {'apple': 3, 'pear': 7, 'orange': 9}
d[orange]= 9
deleted prar d= {'apple': 3, 'orange': 9}
add d= {'apple': 3, 'orange': 9, 'b': 20, 'pig': 100, 1: 12}

同时,字典内还可以放字典,列表等,如打印出字典中apple中的3的内容。

d={'apple':{1:11,3:33,4:44},'pear':[3,7,9,2],'orange':9}   #字典
print(d['apple'][3])

运行结果为33。

25 import

import time模块,运行后显示当然时间。

import timeprint(time.localtime())

或者为了简便书写,把time命名为t,运行后是同样的效果。

import time as tprint(t.localtime())

如果只需要用到个别的内容,可以写from xxx import xxx,xxx

from time import time,localtime
# 此时运用就不需要前缀time.XXXprint(localtime())
print(time())

导入time中所有的功能用*

from time import *
# 此时运用就不需要前缀time.XXXprint(localtime())
print(time())

26 自己的模块

建立自己的模块,在脚本中写如module1的模块,即文件名需要命名为module1

def add(a,b):c=a+bprint('a+b=',c)

要进行调用时,需要在刚刚建立模块的同一目录下建立新的脚本

import module1 as mm.add(5,8)

运行效果:

a+b= 13

对于python默认的自带模块则不需要保持在同一目录,所以对于自己之后建立的很有用的模块可以放在默认路径下,之后直接import即可。默认路径一般在python\Lib\site-packages中放入即可。

27 continue&break

不用continue或break时

a = True
while a:b = input('type something=')#input的内容被当作字符串if b== '1':a = Falseelse:passprint('still in while')print('finish run')

运行结果(当b==1时不是里面跳出循环,而是要将余下全部执行完再结束):

type something=2
still in while
type something=1
still in while
finish run

当使用break时,不是1时打印继续循环,是1时跳出循环,打印finish。

while True:b = input('type something=')#input的内容被当作字符串if b== '1':breakelse:passprint('still in while')print('finish run')

运行结果:

type something=3
still in while
type something=5
still in while
type something=1
finish run

当使用continue时,不是1时打印继续循环,是1时继续执行while中的内容。

while True:b = input('type something=')#input的内容被当作字符串if b== '1':continueelse:passprint('still in while')print('finish run')

运行结果:

type something=2
still in while
type something=1
type something=

28 错误处理try…except…else

以下为简单的try…except…else的语法:

try:
<语句>        #运行别的代码
except <名字>:
<语句>        #如果在try部份引发了'name'异常
except <名字>,<数据>:
<语句>        #如果引发了'name'异常,获得附加的数据
else:
<语句>        #如果没有异常发生

try的工作原理是,当开始一个try语句后,python就在当前程序的上下文中作标记,这样当异常出现时就可以回到这里,try子句先执行,接下来会发生什么依赖于执行时是否出现异常。

  • 如果当try后的语句执行时发生异常,python就跳回到try并执行第一个匹配该异常的except子句,异常处理完毕,控制流就通过整个try语句(除非在处理异常时又引发新的异常)。

  • 如果在try后的语句里发生了异常,却没有匹配的except子句,异常将被递交到上层的try,或者到程序的最上层(这样将结束程序,并打印默认的出错信息)。

  • 如果在try子句执行时没有发生异常,python将执行else语句后的语句(如果有else的话),然后控制流通过整个try语句。
    脚本代码如下(运行第一遍,输入y创建文件,运行第二遍向文件中写入内容ssss):

try:file=open('eeee','r+')
except:print('there is no file named eeee')response = input('do you want to creat a file?')if response =='y':file = open('eeee','w')else:pass
else:file.write('ssss')
file.close()

其中的open(‘filename’, ‘r+’)是打开文件的一种方式,其中’r+'表示以读写模式打开文件。这意味着可以读取文件的内容,也可以向文件写入内容。如果文件不存在,则会创建一个新文件。如果文件已经存在,则会从文件的开头开始读取和写入。

29 zip lambda map

>>> a =[1,2,3]
>>> b = [4,5,6]
>>> zip(a,b)
<zip object at 0x0000026ED9494148>    #运行结果,为一个object,不显示内容
>>> list(zip(a,b))                 #放在list中显示
[(1, 4), (2, 5), (3, 6)] #运行结果
>>> for i,j in zip(a,b):print(i/2,j*2)0.5 8                    #运行结果
1.0 10
1.5 12>>> list(zip(a,b,a)) #zip三组
[(1, 4, 1), (2, 5, 2), (3, 6, 3)]   #运行结果>>> def fun1(x,y):return(x+y)>>> fun1(4,6)
10                  #运行结果
>>> fun2 = lambda x,y:x+y    #运行结果,lambda可以实现def同样的功能
>>> fun2(4,6)
10                  #运行结果
>>> map(fun1,[1],[2])
<map object at 0x0000026ED9494048>    #运行结果,为一个object,不显示内容
>>> list(map(fun1,[1],[2]))
[3]                     #运行结果
>>> list(map(fun1,[1,4],[5]))
[6]                     #运行结果,如果不对应,只计算前一组
>>> list(map(fun1,[1,4],[5,8]))
[6, 12]                 #运行结果

30 浅复制&深复制(copy&deepcopy)

直接用赋值b=a,两者的id一样,可以理解为a,b是同一个东西。改变其中一个另一个也会同时改变,且id保持一致。

a=[1,5,7]
>>> b=a
>>> id(a)
1815267812296
>>> id(b)
1815267812296
>>> a[0]=10       #改变a,b也同时改变
>>> b
[10, 5, 7]
>>> b[1]=20       #改变b,a也同时改变
>>> a
[10, 20, 7]
>>> id(a)==id(b)
True
>>> id(a[0])==id(b[0])
True
>>> id(a[1])==id(b[1])
True
>>> id(a[2])==id(b[2])
True

copy是浅复制,会把浅层的东西复制到别的id,深的不能够复制,所以id不变。

>>> a=[1,2,3]
>>> import copy
>>> c=copy.copy(a)
>>> id(a)==id(c)
False
>>> id(a[0])==id(c[0])  #各个位的值id为什么相同啦,推测是他们表示的是一个相同的数,而找的同一个数的id是相同的
True
>>> id(a[1])==id(c[1])
True
>>> id(a[2])==id(c[2])
True
>>> a[1]=1111 #被复制到别的id,改变a,c不变
>>> c
[1, 2, 3]
>>> a
[1, 1111, 3]
>>> c[1]=2222 #被复制到别的id,改变c,a不变
>>> a
[1, 1111, 3]
>>> c
[1, 2222, 3]

接下来试下深列表的copy

>>> a=[1,2,[3,4]]
>>> import copy
>>> d=copy.copy(a)
>>> d
[1, 2, [3, 4]]
>>> id(a)==id(d)
False
>>> a[0]=33       #改变a,d不变
>>> d
[1, 2, [3, 4]]
>>> a
[33, 2, [3, 4]]
>>> d[1]=55       #改变d,a不变
>>> a
[33, 2, [3, 4]]
>>> d
[1, 55, [3, 4]]>>> d[2][0]=88     #改变d内列表中的第0个值后,a也同时改变
>>> a
[33, 2, [88, 4]]
>>> a[2][1]=99        #改变a内列表中的第1个值后,d也同时改变
>>> d
[1, 55, [88, 99]]

接下来使用deepcopy,这是完全的复制到别的id,改变一个不会影响另一个复制的内容。

>>> import copy
>>> a=[1,2,[3,4]]
>>> e =copy.deepcopy(a)
>>> e
[1, 2, [3, 4]]
>>> id(a) ==id(e)
False
>>> e[2][0]=55
>>> a
[1, 2, [3, 4]]
>>> e
[1, 2, [55, 4]]
>>> a[2][1]=77
>>> e
[1, 2, [55, 4]]
>>> a
[1, 2, [3, 77]]

31 Threading 多线程

Threading 多线程系列视频
Python3 多线程

1 什么是多线程

多线程类似于同时执行多个不同程序,多线程运行有如下优点:

  • 使用线程可以把占据长时间的程序中的任务放到后台去处理。
  • 用户界面可以更加吸引人,比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进度条来显示处理的进度。
  • 程序的运行速度可能加快。
  • 在一些等待的任务实现上如用户输入、文件读写和网络收发数据等,线程就比较有用了。在这种情况下我们可以释放一些珍贵的资源如内存占用等等。

每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。

每个线程都有他自己的一组CPU寄存器,称为线程的上下文,该上下文反映了线程上次运行该线程的CPU寄存器的状态。

指令指针和堆栈指针寄存器是线程上下文中两个最重要的寄存器,线程总是在进程得到上下文中运行的,这些地址都用于标志拥有线程的进程地址空间中的内存。

  • 线程可以被抢占(中断)。
  • 在其他线程正在运行时,线程可以暂时搁置(也称为睡眠) – 这就是线程的退让。

线程可以分为:

  • 内核线程:由操作系统内核创建和撤销。
  • 用户线程:不需要内核支持而在用户程序中实现的线程。

Python3 线程中常用的两个模块为:

  • _thread
  • threading(推荐使用)

thread 模块已被废弃。用户可以使用 threading 模块代替。所以,在 Python3 中不能再使用"thread" 模块。为了兼容性,Python3 将 thread 重命名为 “_thread”。

2 增加线程 add thread

import threadingdef thread_job():print('This is an added,number is %s\n'% threading.current_thread())
def main():added_thread=threading.Thread(target=thread_job)added_thread.start()print(threading.active_count()) #激活的线程数print(threading.enumerate())    #返回当前活动的 Thread 对象列表print(threading.current_thread())#返回当前正在执行的线程对象if __name__=='__main__':#判断是否为主模块,如果是,则运行main()函数main()

其中%s是一个占位符,表示后面要替换的变量或表达式的字符串表示。 具体的替换值由 % 符号后面的内容提供,这里是 threading.current_thread() 函数返回的线程对象。

如果占位符的类型是字符串,那么可以使用 %s;如果占位符的类型是整数,那么可以使用 %d;如果占位符的类型是浮点数,那么可以使用 %f。
例子如下:

name = 'John'
age = 30
height = 1.75print('My name is %s, I am %d years old, and I am %f meters tall.' % (name, age, height))

3 join

在Python中,join()方法是线程类(Thread)的一个方法,它用于等待一个线程完成执行
当在一个线程中调用另一个线程的join()方法时,当前线程将会阻塞,直到被调用的线程执行完成或者超时

join()方法常常用于多线程编程中,以便在主线程中等待所有子线程执行完毕后再继续执行主线程的后续代码。如果没有使用join()方法,那么主线程可能会在子线程还在执行的时候就结束了,从而导致子线程无法完成任务。

join()方法可以传入一个参数,表示最长等待时间。如果被调用的线程在指定时间内没有执行完毕,join()方法会返回并继续执行当前线程的后续代码。如果不传入参数,则会一直等待直到被调用的线程执行完成。

import threading
import time
def T1_job():print('T1 start\n')for i in range(10):time.sleep(0.1)print('T1 finishi\n')def T2_job():print('T2 start\n')print('T2 finish\n')def main():thread1=threading.Thread(target=T1_job,name='T1')thread2 = threading.Thread(target=T2_job,name='T2')thread1.start()thread2.start()thread2.join()thread1.join()print('all done\n')if __name__=='__main__':#判断是否为主模块,如果是,则运行main()函数main()

如果没有上面代码中的join时

     thread2.join()thread1.join()

运行结果输出:

T1 start
T2 start
all doneT2 finish
>>>
T1 finishi

只有thread1.join()时输出:

T1 start
T2 startT2 finishT1 finishiall done

只有thread2.join()时输出:

T1 start
T2 startT2 finishall done>>> T1 finishi

两个线程都有join时输出:

T1 start
T2 startT2 finishT1 finishiall done

4 Queue

Python的Queue模块中提供了同步的、线程安全的队列类,包括FIFO(先入先出)队列Queue,LIFO(后入先出)队列LifoQueue,和优先级队列PriorityQueue。这些队列都实现了锁原语,能够在多线程中直接使用。可以使用队列来实现线程间的同步

通过创建一个Queue实例,我们可以在多个线程之间共享这个实例,并使用put()方法将数据添加到队列中,使用get()方法从队列中获取数据。

import threading
import time
from queue import Queuedef job(l,q):for i in range(len(l)):l[i]=l[i]**2q.put(l)        #线程是无法返回一个值的 def multithreading():q = Queue()threads = []data= [[1,2,3],[3,4,5],[4,5,6],[5,6,7]]for i in range(4):t = threading.Thread(target=job,args=(data[i],q))#job后没有()t.start()threads.append(t)for thread in threads:thread.join()results = []for _ in range(4):results.append(q.get())print(results)if __name__=='__main__':multithreading()

在Python中,我们可以使用threading模块创建线程。当我们创建一个线程时,我们可以使用target参数指定线程要执行的函数。在这个例子中,目标函数是job

除了target参数,threading.Thread()还提供了一个args参数。args是一个元组,它可以包含传递给目标函数的参数。在这个例子中,args参数包含两个值:data[i]和q。这意味着在启动线程时,目标函数job将被调用,并将data[i]和q作为参数传递给它

换句话说,args的作用是将参数传递给目标函数。这使得我们可以轻松地向函数传递多个参数,而不必在函数内部硬编码这些参数。

运行结果:

[[1, 4, 9], [9, 16, 25], [16, 25, 36], [25, 36, 49]]

5 不一定有效率 GIL

Python中单线程、多线程和多进程的效率对比实验

GIL(全局解释器锁)是Python中的一个重要概念,它是一种线程同步机制。在Python解释器中,每个线程都需要获取GIL才能执行,即一次只有一个线程可以在解释器中执行Python字节码。GIL是一个互斥锁,它可以确保同时只有一个线程可以访问Python对象和执行Python字节码。这种机制可以避免多个线程同时修改Python对象和字节码时出现竞争条件和数据不一致的问题。

GIL的存在对于Python的多线程应用程序有以下影响:

  1. 限制了多核CPU的利用:由于GIL的存在,多个线程不能同时执行Python字节码,这意味着Python中的多线程应用程序无法利用多个CPU核心。即使在多线程应用程序中使用多个线程,只有一个线程能够使用CPU,其他线程只能等待GIL的释放。

  2. 对I/O密集型应用程序的影响小:I/O密集型应用程序在执行期间需要等待外部资源(例如网络I/O或磁盘I/O),因此在这些应用程序中,GIL的影响相对较小。因为当一个线程在等待I/O时,其他线程可以获取GIL并执行Python代码。

  3. 对CPU密集型应用程序的影响大:CPU密集型应用程序需要大量的CPU资源,因此在这些应用程序中,GIL的影响相对较大。因为当一个线程执行CPU密集型任务时,其他线程必须等待GIL的释放,这可能会导致性能瓶颈。

需要注意的是,GIL只对解释器级别的Python代码起作用。对于Python中的一些扩展模块(例如numpy和pandas),它们使用的是C语言编写的代码,这些代码可以在不受GIL限制的情况下执行,因此它们可以充分利用多个CPU核心。

import threading
from queue import Queue
import copy
import timedef job(l, q):res = sum(l)q.put(res)def multithreading(l):q = Queue()threads = []for i in range(4):t = threading.Thread(target=job, args=(copy.copy(l), q), name='T%i' % i)t.start()threads.append(t)[t.join() for t in threads]total = 0for _ in range(4):total += q.get()print(total)def normal(l):total = sum(l)print(total)if __name__ == '__main__':l = list(range(1000000))s_t = time.time()normal(l*4)print('normal: ',time.time()-s_t)s_t = time.time()multithreading(l)print('multithreading: ', time.time()-s_t)

6 锁 lock

无锁时:

import threadingdef job1():global A, lockfor i in range(10):A += 1print('job1', A)def job2():global A, lockfor i in range(10):A += 10print('job2', A)if __name__ == '__main__':A = 0t1 = threading.Thread(target=job1)t2 = threading.Thread(target=job2)t1.start()t2.start()t1.join()t2.join()

运行结果很混乱:
实际上是由于都用的A所以被交替使用
0+1=1,1+10为11 输出111
11+1=12,12+10=22 输出1222
+1,+10交替运行

job1job2  111job1job2  1222job1job2  2333job1job2  3444job1job2  4555job1job2  5666job1job2  6777job1job2  7888job1job2  8999job1job2  100110

修改为A,B表示后

import threadingdef job1():global A, lockfor i in range(10):A += 1print('job1 %s '% A)def job2():global B, lockfor i in range(10):B += 10print('job2 %s '% B)if __name__ == '__main__':A = 0B = 0t1 = threading.Thread(target=job1)t2 = threading.Thread(target=job2)t1.start()t2.start()t1.join()t2.join()

运行结果:

job1 1 job2 10 job1 2 job2 20 job1 3 job2 30 job1 4 job2 40 job1 5 job2 50 job1 6 job2 60 job1 7 job2 70 job1 8 job2 80 job1 9 job2 90 job1 10 job2 100

有锁时:
使用lock.acquire()和 lock.release()表示锁的开始与结束。

import threadingdef job1():global A, locklock.acquire()for i in range(10):A += 1print('job1', A)lock.release()def job2():global A, locklock.acquire()for i in range(10):A += 10print('job2', A)lock.release()if __name__ == '__main__':lock = threading.Lock()A = 0t1 = threading.Thread(target=job1)t2 = threading.Thread(target=job2)t1.start()t2.start()t1.join()t2.join()

运行结果:

job1 1
job1 2
job1 3
job1 4
job1 5
job1 6
job1 7
job1 8
job1 9
job1 10
job2 20
job2 30
job2 40
job2 50
job2 60
job2 70
job2 80
job2 90
job2 100
job2 110

32 Multiprocessing 让你的多核计算机发挥真正潜力

Multiprocessing系列视频

1 什么是多进程

在Python中,多进程是指同时运行多个独立的进程,每个进程都有自己的执行空间和系统资源。每个进程都可以独立地运行并执行任务,可以同时执行多个任务,从而实现并行处理。

Python的多进程模块(multiprocessing)可以用来创建和管理多个进程。每个进程都有自己的进程 ID,可以通过它来标识和控制进程的行为。多进程的优点是可以充分利用多核CPU,提高程序的执行效率。

在Python中,可以使用多种方式实现多进程,包括使用multiprocessing模块、使用os模块的fork方法创建子进程、使用subprocess模块调用其他程序等。使用多进程的时候需要注意进程间的通信和同步,避免数据竞争和死锁等问题。

2 创建进程

import multiprocessing as mpdef job(a,b):print('aaaa')if __name__=='__main__':p1 = mp.Process(target=job,args=(1,2))p1.start()p1.join()

3 queue

本例中算了两次job再相加

import multiprocessing as mpdef job(q):res = 0for i in range(1000):res += i+i**2+i**3q.put(res) # queueif __name__ == '__main__':q = mp.Queue()p1 = mp.Process(target=job, args=(q,))p2 = mp.Process(target=job, args=(q,))p1.start()p2.start()p1.join()p2.join()res1 = q.get()res2 = q.get()print(res1+res2)

4 效率对比 multithreading和multiprocessing

在 Python 中,time.time() 函数返回当前时间戳,即从1970年1月1日午夜(UTC/GMT的历元时间)到当前时间的秒数。它返回一个浮点数,通常表示为以秒为单位的小数,例如:1617217878.8957865。该函数常用于计算程序的执行时间。
例子中相减是为了获取程序运行时间。

import multiprocessing as mp
import threading as td
import timedef job(q):res = 0for i in range(1000000):res += i+i**2+i**3q.put(res) # queuedef multicore():q = mp.Queue()p1 = mp.Process(target=job, args=(q,))p2 = mp.Process(target=job, args=(q,))p1.start()p2.start()p1.join()p2.join()res1 = q.get()res2 = q.get()print('multicore:' , res1+res2)def normal():res = 0for _ in range(2):for i in range(1000000):res += i+i**2+i**3print('normal:', res)def multithread():q = mp.Queue()t1 = td.Thread(target=job, args=(q,))t2 = td.Thread(target=job, args=(q,))t1.start()t2.start()t1.join()t2.join()res1 = q.get()res2 = q.get()print('multithread:', res1+res2)if __name__ == '__main__':st = time.time()normal()st1= time.time()print('normal time:', st1 - st)multithread()st2 = time.time()print('multithread time:', st2 - st1)multicore()print('multicore time:', time.time()-st2)

我的电脑运行结果:

normal: 499999666667166666000000
normal time: 1.3881876468658447
multithread: 499999666667166666000000
multithread time: 1.3638417720794678
multicore: 499999666667166666000000
multicore time: 0.8919181823730469

5 进程池 pool

import multiprocessing as mpdef job(x):return x*xdef multicore():pool = mp.Pool(processes=2)res = pool.map(job, range(10))print(res)res = pool.apply_async(job, (2,))print(res.get())multi_res =[pool.apply_async(job, (i,)) for i in range(10)]print([res.get() for res in multi_res])if __name__ == '__main__':multicore()

6 共享内存 shared memory

multiprocessing.Value() 是 Python 中 multiprocessing 模块提供的一个函数,它的作用是创建一个共享变量,可以被多个进程同时访问和修改。

函数的括号内需要传入两个参数,分别是共享变量的类型和初始值。共享变量的类型可以是 ‘c’,‘b’,‘h’,‘i’,‘l’,‘f’ 或 ‘d’ 等基本数据类型的字符表示,分别表示 char,bool,short,int,long,float 和 double 类型的共享变量。初始值则是共享变量的初始值,可以是对应类型的任意合法值。

例如,可以通过以下代码创建一个整型共享变量 x,初始值为 0:

from multiprocessing import Valuex = Value('i', 0)

这样,在多个进程中可以通过 x.value 访问和修改这个共享变量的值,而且多个进程对共享变量的修改操作是同步的,不会出现数据竞争的问题

7 lock锁

import multiprocessing as mp
import timedef job(v, num, l):l.acquire()for _ in range(10):time.sleep(0.1)v.value += numprint(v.value)l.release()def multicore():l = mp.Lock()v = mp.Value('i', 0)p1 = mp.Process(target=job, args=(v, 1, l))p2 = mp.Process(target=job, args=(v, 3, l))p1.start()p2.start()p1.join()p2.join()if __name__ == '__main__':multicore()

<错误:无输出>

33 Tkinter 做简单的窗口视窗 Python GUI

1 Tkinter是什么

Tkinter 是使用 python 进行窗口视窗设计的模块。Tkinter模块(“Tk 接口”)是Python的标准Tk GUI工具包的接口。作为 python 特定的GUI界面,是一个图像的窗口,tkinter是python 自带的,可以编辑的GUI界面,我们可以用GUI 实现很多直观的功能,比如想开发一个计算器,如果只是一个程序输入,输出窗口的话,是没用用户体验的。所有开发一个图像化的小窗口,就是必要的。

对于稍有GUI编程经验的人来说,Python的Tkinter界面库是非常简单的。python的GUI库非常多,选择Tkinter,一是最为简单,二是自带库,不需下载安装,随时使用,三则是从需求出发,Python作为一种脚本语言,一种胶水语言,一般不会用它来开发复杂的桌面应用,它并不具备这方面的优势,使用Python,可以把它作为一个灵活的工具,而不是作为主要开发语言,那么在工作中,需要制作一个小工具,肯定是需要有界面的,不仅自己用,也能分享别人使用,在这种需求下,Tkinter是足够胜任的!

2 Label & Button标签和按钮

import tkinter as tkwindow = tk.Tk()
window.title('my window')
window.geometry('200x100')var = tk.StringVar()
l = tk.Label(window, textvariable=var, bg='green', font=('Arial', 12), width=15,height=2)
#l = tk.Label(window, text='OMG! this is TK!', bg='green', font=('Arial', 12), width=15, height=2)
l.pack()on_hit = False
def hit_me():global on_hitif on_hit == False:on_hit = Truevar.set('you hit me')else:on_hit = Falsevar.set('')b = tk.Button(window, text='hit me', width=15,height=2, command=hit_me)
b.pack()window.mainloop()

3 Entry & Text输入,文本框

import tkinter as tkwindow = tk.Tk()
window.title('my window')
window.geometry('200x200')
# e = tk.Entry(window, show="*")
e = tk.Entry(window, show="1")
e.pack()def insert_point():var = e.get()t.insert('insert', var)
def insert_end():var = e.get()# t.insert('end', var)t.insert(2.2, var)b1 = tk.Button(window, text='insert point', width=15,height=2, command=insert_point)
b1.pack()
b2 = tk.Button(window, text='insert end',command=insert_end)
b2.pack()
t = tk.Text(window, height=2)
t.pack()window.mainloop()

4 Listbox列表部件

import tkinter as tkwindow = tk.Tk()
window.title('my window')
window.geometry('200x200')var1 = tk.StringVar()
l = tk.Label(window, bg='yellow', width=4, textvariable=var1)
l.pack()def print_selection():value = lb.get(lb.curselection())var1.set(value)b1 = tk.Button(window, text='print selection', width=15,height=2, command=print_selection)
b1.pack()var2 = tk.StringVar()
var2.set((11,22,33,44))
lb = tk.Listbox(window, listvariable=var2)
list_items = [1,2,3,4]
for item in list_items:lb.insert('end', item)
lb.insert(1, 'first')
lb.insert(2, 'second')
lb.delete(2)
lb.pack()window.mainloop()

5 Radiobutton选择按钮

import tkinter as tkwindow = tk.Tk()
window.title('my window')
window.geometry('200x200')var = tk.StringVar()
l = tk.Label(window, bg='yellow', width=20, text='empty')
l.pack()def print_selection():l.config(text='you have selected ' + var.get())r1 = tk.Radiobutton(window, text='Option A',variable=var, value='A',command=print_selection)
r1.pack()
r2 = tk.Radiobutton(window, text='Option B',variable=var, value='B',command=print_selection)
r2.pack()
r3 = tk.Radiobutton(window, text='Option C',variable=var, value='C',command=print_selection)
r3.pack()window.mainloop()

6 Scale尺度

import tkinter as tkwindow = tk.Tk()
window.title('my window')
window.geometry('200x200')l = tk.Label(window, bg='yellow', width=20, text='empty')
l.pack()def print_selection(v):l.config(text='you have selected ' + v)s = tk.Scale(window, label='try me', from_=5, to=11, orient=tk.HORIZONTAL,length=200, showvalue=0, tickinterval=2, resolution=0.01, command=print_selection)
s.pack()window.mainloop()

7 Checkbutton勾选项

import tkinter as tkwindow = tk.Tk()
window.title('my window')
window.geometry('200x200')l = tk.Label(window, bg='yellow', width=20, text='empty')
l.pack()def print_selection():if (var1.get() == 1) & (var2.get() == 0):l.config(text='I love only Python ')elif (var1.get() == 0) & (var2.get() == 1):l.config(text='I love only C++')elif (var1.get() == 0) & (var2.get() == 0):l.config(text='I do not love either')else:l.config(text='I love both')var1 = tk.IntVar()
var2 = tk.IntVar()
c1 = tk.Checkbutton(window, text='Python', variable=var1, onvalue=1, offvalue=0,command=print_selection)
c2 = tk.Checkbutton(window, text='C++', variable=var2, onvalue=1, offvalue=0,command=print_selection)
c1.pack()
c2.pack()window.mainloop()

8 Canvas 画布

图片命名ins.gif放在同一文件夹中。

import tkinter as tkwindow = tk.Tk()
window.title('my window')
window.geometry('200x200')canvas = tk.Canvas(window, bg='blue', height=100, width=200)
image_file = tk.PhotoImage(file='ins.gif')
image = canvas.create_image(10, 10, anchor='nw', image=image_file)
x0, y0, x1, y1= 50, 50, 80, 80
line = canvas.create_line(x0, y0, x1, y1)
oval = canvas.create_oval(x0, y0, x1, y1, fill='red')
arc = canvas.create_arc(x0+30, y0+30, x1+30, y1+30, start=0, extent=180)
rect = canvas.create_rectangle(100, 30, 100+20, 30+20)
canvas.pack()def moveit():canvas.move(rect, 0, 2)b = tk.Button(window, text='move', command=moveit).pack()window.mainloop()

9 Menubar 菜单

import tkinter as tkwindow = tk.Tk()
window.title('my window')
window.geometry('200x200')l = tk.Label(window, text='', bg='yellow')
l.pack()
counter = 0
def do_job():global counterl.config(text='do '+ str(counter))counter+=1menubar = tk.Menu(window)
filemenu = tk.Menu(menubar, tearoff=0)
menubar.add_cascade(label='File', menu=filemenu)
filemenu.add_command(label='New', command=do_job)
filemenu.add_command(label='Open', command=do_job)
filemenu.add_command(label='Save', command=do_job)
filemenu.add_separator()
filemenu.add_command(label='Exit', command=window.quit)editmenu = tk.Menu(menubar, tearoff=0)
menubar.add_cascade(label='Edit', menu=editmenu)
editmenu.add_command(label='Cut', command=do_job)
editmenu.add_command(label='Copy', command=do_job)
editmenu.add_command(label='Paste', command=do_job)submenu = tk.Menu(filemenu)
filemenu.add_cascade(label='Import', menu=submenu, underline=0)
submenu.add_command(label="Submenu1", command=do_job)window.config(menu=menubar)window.mainloop()

10 Frame框架

import tkinter as tkwindow = tk.Tk()
window.title('my window')
window.geometry('200x200')
tk.Label(window, text='on the window').pack()frm = tk.Frame(window)
frm.pack()
frm_l = tk.Frame(frm, )
frm_r = tk.Frame(frm)
frm_l.pack(side='left')
frm_r.pack(side='right')tk.Label(frm_l, text='on the frm_l1').pack()
tk.Label(frm_l, text='on the frm_l2').pack()
tk.Label(frm_r, text='on the frm_r1').pack()
window.mainloop()

11 messagebox弹窗

import tkinter as tk
import tkinter.messageboxwindow = tk.Tk()
window.title('my window')
window.geometry('200x200')def hit_me():#tk.messagebox.showinfo(title='Hi', message='hahahaha')   # return 'ok'#tk.messagebox.showwarning(title='Hi', message='nononono')   # return 'ok'#tk.messagebox.showerror(title='Hi', message='No!! never')   # return 'ok'#print(tk.messagebox.askquestion(title='Hi', message='hahahaha'))   # return 'yes' , 'no'#print(tk.messagebox.askyesno(title='Hi', message='hahahaha'))   # return True, Falseprint(tk.messagebox.asktrycancel(title='Hi', message='hahahaha'))   # return True, Falseprint(tk.messagebox.askokcancel(title='Hi', message='hahahaha'))   # return True, Falseprint(tk.messagebox.askyesnocancel(title="Hi", message="haha"))     # return, True, False, Nonetk.Button(window, text='hit me', command=hit_me).pack()
window.mainloop()

12 pack grid place放置位置

import tkinter as tkwindow = tk.Tk()
window.geometry('200x200')#canvas = tk.Canvas(window, height=150, width=500)
#canvas.grid(row=1, column=1)
#image_file = tk.PhotoImage(file='welcome.gif')
#image = canvas.create_image(0, 0, anchor='nw', image=image_file)#tk.Label(window, text='1').pack(side='top')
#tk.Label(window, text='1').pack(side='bottom')
#tk.Label(window, text='1').pack(side='left')
#tk.Label(window, text='1').pack(side='right')#for i in range(4):#for j in range(3):#tk.Label(window, text=1).grid(row=i, column=j, padx=10, pady=10)tk.Label(window, text=1).place(x=20, y=10, anchor='nw')window.mainloop()

13例子1登录窗口

图片命名welcome.gif放在同一文件的中。

import tkinter as tkwindow = tk.Tk()
window.title('Welcome to Mofan Python')
window.geometry('450x300')# welcome image
canvas = tk.Canvas(window, height=200, width=500)
image_file = tk.PhotoImage(file='welcome.gif')
image = canvas.create_image(0,0, anchor='nw', image=image_file)
canvas.pack(side='top')# user information
tk.Label(window, text='User name: ').place(x=50, y= 150)
tk.Label(window, text='Password: ').place(x=50, y= 190)var_usr_name = tk.StringVar()
var_usr_name.set('example@python.com')
entry_usr_name = tk.Entry(window, textvariable=var_usr_name)
entry_usr_name.place(x=160, y=150)
var_usr_pwd = tk.StringVar()
entry_usr_pwd = tk.Entry(window, textvariable=var_usr_pwd, show='*')
entry_usr_pwd.place(x=160, y=190)def usr_login():pass
def usr_sign_up():pass# login and sign up button
btn_login = tk.Button(window, text='Login', command=usr_login)
btn_login.place(x=170, y=230)
btn_sign_up = tk.Button(window, text='Sign up', command=usr_sign_up)
btn_sign_up.place(x=270, y=230)window.mainloop()

14例子1登录窗口

import tkinter as tk
import picklewindow = tk.Tk()
window.title('Welcome to Mofan Python')
window.geometry('450x300')# welcome image
canvas = tk.Canvas(window, height=200, width=500)
image_file = tk.PhotoImage(file='welcome.gif')
image = canvas.create_image(0,0, anchor='nw', image=image_file)
canvas.pack(side='top')# user information
tk.Label(window, text='User name: ').place(x=50, y= 150)
tk.Label(window, text='Password: ').place(x=50, y= 190)var_usr_name = tk.StringVar()
var_usr_name.set('example@python.com')
entry_usr_name = tk.Entry(window, textvariable=var_usr_name)
entry_usr_name.place(x=160, y=150)
var_usr_pwd = tk.StringVar()
entry_usr_pwd = tk.Entry(window, textvariable=var_usr_pwd, show='*')
entry_usr_pwd.place(x=160, y=190)def usr_login():usr_name = var_usr_name.get()usr_pwd = var_usr_pwd.get()try:with open('usrs_info.pickle', 'rb') as usr_file:usrs_info = pickle.load(usr_file)except FileNotFoundError:with open('usrs_info.pickle', 'wb') as usr_file:usrs_info = {'admin': 'admin'}pickle.dump(usrs_info, usr_file)if usr_name in usrs_info:if usr_pwd == usrs_info[usr_name]:tk.messagebox.showinfo(title='Welcome', message='How are you? ' + usr_name)else:tk.messagebox.showerror(message='Error, your password is wrong, try again.')else:is_sign_up = tk.messagebox.askyesno('Welcome','You have not sign up yet. Sign up today?')if is_sign_up:usr_sign_up()def usr_sign_up():pass# login and sign up button
btn_login = tk.Button(window, text='Login', command=usr_login)
btn_login.place(x=170, y=230)
btn_sign_up = tk.Button(window, text='Sign up', command=usr_sign_up)
btn_sign_up.place(x=270, y=230)window.mainloop()

15例子1登录窗口

import tkinter as tk
from tkinter import messagebox  # import this to fix messagebox error
import picklewindow = tk.Tk()
window.title('Welcome to Mofan Python')
window.geometry('450x300')# welcome image
canvas = tk.Canvas(window, height=200, width=500)
image_file = tk.PhotoImage(file='welcome.gif')
image = canvas.create_image(0,0, anchor='nw', image=image_file)
canvas.pack(side='top')# user information
tk.Label(window, text='User name: ').place(x=50, y= 150)
tk.Label(window, text='Password: ').place(x=50, y= 190)var_usr_name = tk.StringVar()
var_usr_name.set('example@python.com')
entry_usr_name = tk.Entry(window, textvariable=var_usr_name)
entry_usr_name.place(x=160, y=150)
var_usr_pwd = tk.StringVar()
entry_usr_pwd = tk.Entry(window, textvariable=var_usr_pwd, show='*')
entry_usr_pwd.place(x=160, y=190)def usr_login():usr_name = var_usr_name.get()usr_pwd = var_usr_pwd.get()try:with open('usrs_info.pickle', 'rb') as usr_file:usrs_info = pickle.load(usr_file)except FileNotFoundError:with open('usrs_info.pickle', 'wb') as usr_file:usrs_info = {'admin': 'admin'}pickle.dump(usrs_info, usr_file)if usr_name in usrs_info:if usr_pwd == usrs_info[usr_name]:tk.messagebox.showinfo(title='Welcome', message='How are you? ' + usr_name)else:tk.messagebox.showerror(message='Error, your password is wrong, try again.')else:is_sign_up = tk.messagebox.askyesno('Welcome','You have not signed up yet. Sign up today?')if is_sign_up:usr_sign_up()def usr_sign_up():def sign_to_Mofan_Python():np = new_pwd.get()npf = new_pwd_confirm.get()nn = new_name.get()with open('usrs_info.pickle', 'rb') as usr_file:exist_usr_info = pickle.load(usr_file)if np != npf:tk.messagebox.showerror('Error', 'Password and confirm password must be the same!')elif nn in exist_usr_info:tk.messagebox.showerror('Error', 'The user has already signed up!')else:exist_usr_info[nn] = npwith open('usrs_info.pickle', 'wb') as usr_file:pickle.dump(exist_usr_info, usr_file)tk.messagebox.showinfo('Welcome', 'You have successfully signed up!')window_sign_up.destroy()window_sign_up = tk.Toplevel(window)window_sign_up.geometry('350x200')window_sign_up.title('Sign up window')new_name = tk.StringVar()new_name.set('example@python.com')tk.Label(window_sign_up, text='User name: ').place(x=10, y= 10)entry_new_name = tk.Entry(window_sign_up, textvariable=new_name)entry_new_name.place(x=150, y=10)new_pwd = tk.StringVar()tk.Label(window_sign_up, text='Password: ').place(x=10, y=50)entry_usr_pwd = tk.Entry(window_sign_up, textvariable=new_pwd, show='*')entry_usr_pwd.place(x=150, y=50)new_pwd_confirm = tk.StringVar()tk.Label(window_sign_up, text='Confirm password: ').place(x=10, y= 90)entry_usr_pwd_confirm = tk.Entry(window_sign_up, textvariable=new_pwd_confirm, show='*')entry_usr_pwd_confirm.place(x=150, y=90)btn_comfirm_sign_up = tk.Button(window_sign_up, text='Sign up', command=sign_to_Mofan_Python)btn_comfirm_sign_up.place(x=150, y=130)# login and sign up button
btn_login = tk.Button(window, text='Login', command=usr_login)
btn_login.place(x=170, y=230)
btn_sign_up = tk.Button(window, text='Sign up', command=usr_sign_up)
btn_sign_up.place(x=270, y=230)window.mainloop()

【莫烦Python】Python 基础教程学习笔记与代码相关推荐

  1. python机器学习基础教程-学习笔记(一)

    了解 scikit-learn 及其用法是很重要的,但还有其他一些库也可以改善你的编程体验. scikit-learn 是基于 NumPy 和 SciPy 科学计算库的.此外,我们还会用到 panda ...

  2. linux磁盘符变化autofs,Linux基础教程学习笔记之Autofs自动挂载

    Linux基础教程学习笔记之Autofs自动挂载 Autofs自动挂载: yum -y install autofs vim /etc/auto.master  在文件中添加下面行 /home/gue ...

  3. 网络存储 linux 访问,Linux基础教程学习笔记28——使用Samba访问网络存储

    Linux基础教程学习笔记28--使用Samba访问网络存储 SMB用于Windows和类Linux系统直接的文件共享 安装samba client包: [root@linuxidc~]# yum i ...

  4. 黑马程序员最新版JavaWeb基础教程-学习笔记

    da@黑马程序员最新版JavaWeb基础教程-学习笔记 day06-HTML&CSS HTML HTML(HyperTest Markup Language):超文本标记语言 是一门语言,所有 ...

  5. 【小甲鱼】python零基础入门学习笔记 03讲~43讲

    本篇基于[莫烦]python基础教程,属于查漏补缺 建议学习顺序 小甲鱼->莫烦numpy&pandas 目录 第003讲 插曲之变量和字符串 课堂笔记 变量 变量 需要注意的地方 字符 ...

  6. 【莫烦Python】Python 基础教程——学习笔记

    文章目录 本笔记基于p1-p29[莫烦Python]Python 基础教程 大家可以根据代码内容和注释进行学习. 安装 我的:python3.8+anaconda+VS code print() pr ...

  7. Python基础教程学习笔记:第一章 基础知识

    Python基础教程 第二版 学习笔记 1.python的每一个语句的后面可以添加分号也可以不添加分号:在一行有多条语句的时候,必须使用分号加以区分 2.查看Python版本号,在Dos窗口中输入&q ...

  8. Matplotlib Python 画图工具包教程学习笔记4 等高线图以及3D图形的画法

    文章目录 1.等高线图 1.1 meshgrid 1.2 plt.contourf 1.3 plt.contour 1.4 plt.clabe 1.5 测试代码 1.6 最终效果 2. 3D图形的绘制 ...

  9. python笔记基础-Python入门基础知识学习笔记之一

    为什么要写这篇文章? 本人做过Objective-C开发,现在在用C#做WinForm开发.近段时间在学习Python入门基础知识时,发现有很多知识点和Objective-C的不一样.故想通过本文记录 ...

最新文章

  1. opensips中db_default_url解析存在的bug
  2. SSMSSH项目中 springmvc 乱码问题解决
  3. python3实现mysql导出excel
  4. python turtle画气球-python windows下显示托盘区气球消息
  5. 邮件服务 交换空间(虚拟内存) 配置链路聚合 配置IPv6地址
  6. numpy.exp()简单理解
  7. 04-numpy-笔记-transpose
  8. Matplotlib 中文显示方框 最简单解决方案
  9. 数字图像处理(作业一)——matlab工具箱初探
  10. 为什么很多人转行学习Web前端技术?
  11. java基础知识---IO常用基础操作(二)
  12. 嵌入式工程师是青春饭吗?越老越吃香吗?
  13. 更新pip下载jupyter lab
  14. CSS实现旋转木马效果
  15. Android用户注册界面设计
  16. MATLAB机器人可视化运动仿真
  17. Bluedroid 打开蓝牙流程
  18. 路由器打印机服务器系统,路由器当打印机服务器
  19. 【工大SCIR】对话中的情感分析与生成简述
  20. 嵌入式工程师的2022 || 2023

热门文章

  1. Spark面试,Spark面试题,Spark面试汇总
  2. Android App Shortcuts
  3. include,include_once,require,require_once的区别
  4. Modbus编程实践
  5. 运筹学基础(名词解释题总结)
  6. 四个适合空闲时间自我提升的软件
  7. 如何快速了解一个系统
  8. 婚姻介绍所怎么做身份实名认证?
  9. PJzhang:关闭wps小广告和快速关闭445端口
  10. 腾讯云服务器入门使用指南教程 新手必看教程