python 文档
[TOC]
这个是基于莫凡python,廖雪峰的自学整理
安装
安装python31
brew install python3
选择python3 —version
atom 安装 script
cmd shift +p 查找 run 快捷键cmd i
打开setting:cmd + ,1
pip3 install jupyter
这边用conda更方便
基础功能
print 功能
Print 功能:
- Print(1) 3.5以上一定要有括号
- Print string的话 用单引号或者双引号,双引号里面加单引号
- \是系统识别符号,数字不可以加字符串
坚持使用4个空格的缩进
大小写敏感的
平方是2**2
,2**3三次方,
8%3是取余数,
9//4取整1
2
3print(int('2')+3) #int为定义整数型
print(int(1.9)) #当int一个浮点型数时,int会保留整数部分
print(float('1.2')+3) #float()是浮点型,可以把字符串转换成小数
格式化
用%实现
- %s表示用字符串替换
- %d表示用整数替换
- 有几个%?占位符,后面就跟几个变量或者值,顺序要对应好。如果只有一个%?,括号可以省略。
- %s永远起作用
%s 字符串 (采用str()的显示)
%r 字符串 (采用repr()的显示)
%c 单个字符
%b 二进制整数
%d 十进制整数
%i 十进制整数
%o 八进制整数
%x 十六进制整数
%e 指数 (基底写为e)
%E 指数 (基底写为E)
%f 浮点数
%F 浮点数,与上相同%g 指数(e)或浮点数 (根据显示长度)
%G 指数(E)或浮点数 (根据显示长度)
%% 字符”%”1
2
3print ('Hi, %s, you have $%d.' % ('Michael', 1000000))
print( 'growth rate: %d %%' % 7)
print( 'Age: %s. Gender: %s' % (25, True))
定义变量
1 | apple=1 |
循环
条件判断
注意不要少写了冒号:1
2
3
4
5
6
7age = 3
if age >= 18:
print('adult')
elif age >= 6:
print('teenager')
else:
print(‘kid')
// //
while循环
循环是while循环,只要条件满足,就不断循环,条件不满足时退出循环。
如果要提前结束循环,可以用break语句1
2
3
4
5
6
7n = 1
while n <= 100:
if n > 10: # 当n = 11时,条件满足,执行break语句
break # break语句会结束当前循环
print(n)
n = n + 1
print('END')
continue和break,pass
1 | n = 0 |
for循环
for…in…循环作为迭代器,cmd+[改变tab缩进结构
依次把list或tuple中的每个元素迭代出来,迭代器的作用,
看例子:1
2
3names = ['Michael', 'Bob', 'Tracy']
for name in names:
print(name)
range是自定义函数,range(1,10)其实是1-91
2
3
4sum = 0
for x in range(101): # 到100
sum = sum + x
print(sum)
if判断
python 语言中等号的判断使用 == 而不是 =, 因为后一种是赋值语句
要有冒号,<,>.<=,<=,==(等于),!=(不等于),
1 | x = 1 |
if…else…
同等关系,都有冒号1
2
3
4if condition:
true_expressions
else:
false_expressions
1 | x = 1 |
if..elif…else
1 | if condition1: |
1 | x = 4 |
定义功能
定义函数
四个空格1
2def function_name(parameters):
expressions
函数参数
1 | def fun1(a,b): |
函数的默认参数
没有的放前面,后面有默认的放后面,这样就可以直接输出了1
2
3
4
5def sale_car(price, color='red', brand='carmy', is_second_hand=True):
print('price', price,
'color', color,
'brand', brand,
'is_second_hand', is_second_hand,)
可变参数(可变参数在函数定义不能出现在特定参数和默认参数前面)和关键词参数(参数在函数内部自动封装成一个字典(dict))1
universal_func(*args, **kw)
定义变量
局部变量 和 全局变量
全局通常全部大写,局部变量小写在函数内;如果在方程中1
2
3a=None
def fun()
global a=30
模块安装
用别人好的外部模块加载,比如numpy1
2
3pip install numpy # 这是 python2+ 版本的用法
pip3 install numpy # 这是 python3+ 版本的用法
pip3 install -U numpy # 这是 python3+ 版本的用法
文件读写
就是存模块、文件,下一次再用;
\n 是换行命令,\t 对齐1
2text='This is my first test.\n\tThis is the second line.\n\tThis the third line'
print(text) # 输入换行命令\n,要注意斜杆的方向。open读文件方式
使用 open 能够打开一个文件, open 的第一个参数为文件名和路径 ‘my file.txt’, 第二个参数为将要以什么方式打开它, 比如 w 为可写方式. 如果计算机没有找到 ‘my file.txt’ 这个文件, w 方式能够创建一个新的文件, 并命名为 my file.txt1
2
3my_file=open('my file.txt','w') #用法: open('文件名','形式'), 其中形式有'w':write;'r':read.
my_file.write(text) #该语句会写入先前定义好的 text
my_file.close() #关闭文件打开文件要close
给文件添加内容
写文件是用,’w’;追加用’a’1
2
3
4append_text='\nThis is appended file.' # 为这行文字提前空行 "\n"
my_file=open('my file.txt','a') # 'a'=append 以增加内容的形式打开
my_file.write(append_text)
my_file.close()读文件,是 r
使用 file.read() 能够读取到文本的所有内容.1
2
3file= open('my file.txt','r')
content=file.read()
print(content)按行读取 file.readline(),readlines就是多行输出
1
2
3
4
5file= open('my file.txt','r')
content=file.readline() # 读取第一行
second_read_time=file.readline() # 读取第二行
print(content)
print(second_read_time)
类 Class
- 建议首字母大写
- 冒号不能缺失
- 运行时class要加()
- def第一个参数要是self运行:
1
2
3
4
5
6
7
8
9
10
11
12
13
14class Calculator: #首字母要大写,冒号不能缺
name='Good Calculator' #该行为class的属性
price=18
def add(self,x,y):
print(self.name)
result = x + y
print(result)
def minus(self,x,y):
result=x-y
print(result)
def times(self,x,y):
print(x*y)
def divide(self,x,y):
print(x/y)cal=Calculator()
cal.add(10,20)
class的init功能
其实 __init__可以理解成初始化class的变量,取自英文中initial 最初的意思.可以在运行时,给初始值附值
- 还是要有self,必须要有参数,不论是先输入的还是默认的
1 | class Calculator: |
input模块
variable=input() 表示运行后,可以在屏幕中输入一个数字,该数字会赋值给自变量。1
2a_input=input('please input a number:')
print('this number is:',a_input)
这儿可以用在if里面,但是在if语句中自变量 a_input 对应的是1 and 2 整数型。输入的内容和判断句中对应的内容格式应该一致。不然返回值是string 所以要是int,或者就是’1’,或者str(1),不然就是int(input(‘plz give a num’))1
2
3
4
5
6
7a_input=int(input('please input a number:'))#注意这里要定义一个整数型
if a_input==1:
print('This is a good one')
elif a_input==2:
print('See you next time')
else:
print('Good luck')
元组(tuple) 列表(List)
两个都是有次序的数字
turple 小括号
list 中括号1
2
3a_tuple = (12, 3, 5, 15 , 6)
another_tuple = 12, 3, 5, 15 , 6 #tuple
a_list = [12, 3, 67, 7, 82] #list
用作迭代,或者定位 参加for..in..循环
依次输出a_tuple和a_list中的各个元素,这儿的range,还是迭代器,是4,从0开始1
2for index in range(len(a_list)):
print("index = ", index, ", number in list = ", a_list[index])
List
list的添加方法:XX.append(‘str’),在最后添加一个
指定位置: xx.insert(位置,‘项目’);
删除:xx.remove(元素),会删掉第一个出现的元素,后面会保留
指数[0]:print(a[0]) :打印出a列表的第0位
a[-1]:从最后面开始算起
a[0:3]:从第0位到第2位,0,1,2,等同于[:3],a[3:5]输出3,4;
还有[5:], [-3:],都是前闭后开
a.index(2):第一次出现2(value)的索引
a.count(2):算出value出现的次数
a.sort():函数排序,从小到大并覆盖
1
2
3
4
5
6
7classmates.append('Adam')
classmates.insert(1, 'Jack') #在第一位添加jack
a = [4,1,2,3,4,1,1,-1]
a.remove(2)
a.sort() # 默认从小到大排序
a.sort(reverse=True) # 从大到小排序
print(a)
tuple和list非常类似,但是tuple一旦初始化就不能修改,“指向不变”.
dictionary 类型
字典没有顺序,字典每一key对应一个value,key可以是int可以str
- 赋值
- 输出位置
- 删除
- 储存类型:字典里面再加字典,也可是fun()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22dic = {'apple':1,'pear':2}
d={1:'a',2:'b'}
dic['lan'] = 'python'
dic['version'] = 2.7
for key in dic:
print(key, dic[key])
a_list = [1,2,3,4,5,6,7,8]
print(a_list[0]) # 1列表
d1 = {'apple':1, 'pear':2, 'orange':3}
print(d1['apple']) # 1字典 输出
del d1['pear'] #删除
d1['platform'] = 64 #赋值
def func():
return 0
d4 = {'apple':[1,2,3], 'pear':{1:3, 3:'a'}, 'orange':func}
print(d4['pear'][3]) # a
set 类型
找不同,不需要value,可以只有key,没有序列
不能传列表+字符串
1 | s = set(['python', 'python2', 'python3','python']) |
添加:1
2
3
4unique_char = set(char_list)
unique_char.add('x')
# unique_char.add(['y', 'z']) this is wrong,不能加一个list和重复的数字
print(unique_char)
清除一个元素可以用 remove 或者 discard, 而清除全部可以用 clear.1
2
3unique_char.remove('x') #这个返回值就是none
unique_char.discard('d')
unique_char.clear()
筛选:.difference .intersection1
2
3unique_char = set(char_list)
print(unique_char.difference({'a', 'e', 'i'})) #不同
print(unique_char.intersection({'a', 'e', 'i'}))
Python 共内置了 list、 tuple 、dict 和 set 四种基本集合,每个集合对象都能够迭代。
dist和set名值对
请务必注意,dict内部存放的顺序和key放入的顺序是没有关系的。需要牢记的第一条就是dict的key必须是不可变对象
和list比较,dict有以下几个特点:
- 查找和插入的速度极快,不会随着key的增加而变慢;
- 需要占用大量的内存,内存浪费多。
而list相反: - 查找和插入的时间随着元素的增加而增加;
- 占用空间小,浪费内存很少。
set和dict的唯一区别仅在于没有存储对应的value,但是,set的原理和dict一样,所以,同样不可以放入可变对象,因为无法判断两个可变对象是否相等,也就无法保证set内部“不会有重复元素”。字符串、整数等都是不可变的,因此,可以放心地作为key。而list是可变的,就不能作为key
多维列表
numpy 和 pandas来处理
多维,两个括号1
2
3
4
5a = [1,2,3,4,5] # 一行五列
multi_dim_a = [[1,2,3],
[2,3,4],
[3,4,5]] # 三行三列
print(multi_dim_a[0][1]) 第0行第1列,就是输出2,都是从0还是索引的
import 一个模块
方法11
2import time
print(time.localtime()) #这样就可以print 当地时间
方法21
2import time as t
print(t.localtime()) # 需要加t.前缀来引出功能
方法三:from time import time,localtime ,只import自己想要的功能.所用功能就是,可以省略模块名。1
2
3
4
5from time import time, localtime
print(localtime())
print(time())
from time import *
自己的模块
保存好模块 xx.py,在同一个目录下即可,在Mac系统中,下载的python模块会被存储到外部路径site-packages,同样,我们自己建的模块也可以放到这个路径,最后不会影响到自建模块的调用。(Library-framework-lib-python-….)1
import balance
其他
try的错误处理
处理错误
输出错误的方法:try: , except … as …:1
2
3
4
5
6
7
8
9
10
11
12try:
file=open('eeee.txt','r+') #这边是读取加写入的操作
except Exception as e:
print(e)
response = input('do you want to create a new file:')
if response=='y':
file=open('eeee.txt','w')
else:
pass
else:
file.write('ssss')
file.close()
zip lambda map
zip函数接受任意多个(包括0个和1个)序列作为参数,合并后返回一个tuple列表.需要list,这个是数项合并1
2
3
4
5
6a=[1,2,3]
b=[4,5,6]
ab=zip(a,b)
print(list(ab)) #需要加list来可视化这个功能
for i,j in zip(a,b): #包括迭代器功能
print(i/2,j*2)
lambda定义一个简单的函数,实现简化代码的功能,看代码会更好理解。
1 | fun= lambda x,y:x+y |
map
map是把函数和参数绑定在一起。1
2
3
4
5
6
7
8
9
10def fun(x,y):
return (x+y)
list(map(fun,[1],[2])) #这边要list这个函数运算
"""
[3]
"""
list(map(fun,[1,2],[3,4]))
"""
[4,6]
"""
copy & deepcopy 浅复制 & 深复制
copy是一个模块
深拷贝:改变一个变量,另一个也改变,他们指针位置一样,内存空间改变。
浅拷贝:第一层列表是完全指定到另外的内存空间,第二层列表旨在在同一个空间,此时第二层可以变,第一层不变。
a=b:内存空间不变。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21import copy
a = [1,2,3]
b = a
b[1]=22
print(a)
print(id(a) == id(b)) #True
# deep copy
c = copy.deepcopy(a)
print(id(a) == id(c)) #false
c[1] = 2
print(a) #[1,2,3]
a[1] = 111 #[1,2,3]
print(c)
# shallow copy
a = [1,2,[3,4]]
d = copy.copy(a)
print(id(a) == id(d)) #false 改变,第一层内存改变
print(id(a[2]) == id(d[2])) #true 第二层不变,包括内存
多线程和多进程
threading 和 multiprocessing
多线程 Threading 是一种让程序拥有分身效果. 能同时处理多件事情. 一般的程序只能从上到下一行行执行代码, 不过 多线程 (Threading) 就能打破这种限制. 让你的程序鲜活起来.
我们在多线程 (Threading) 里提到过, 它是有劣势的, GIL 让它没能更有效率的处理一些分摊的任务. 而现在的电脑大部分配备了多核处理器, 多进程 Multiprocessing 能让电脑更有效率的分配任务给每一个处理器, 这种做法解决了多线程的弊端. 也能很好的提升效率.
多线程
添加线程threading
加载thereading模块
几个函数:
- threading.active.acount() ,有几个线程
- threading.enumerate(),查看所有线程信息
- threading.current_thread(),正在运行的线程
1 |
|
join功能
线程任务还未完成便输出all done。如果要遵循顺序,可以在启动线程后对它调用join1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19import threading
import time
def T1_job():
print("T1 start\n")
for i in range(10):
time.sleep(0.1)
print("T1 finish\n")
def T2_job():
print("T2 start\n")
print("T2 finish\n")
thread_1 = threading.Thread(target=T1_job, name='T1')
thread_2 = threading.Thread(target=T2_job, name='T2')
thread_1.start() # 开启T1
thread_2.start() # 开启T2
thread_2.join() # join for T2
thread_1.join() # join for T1
print("all done\n")
储存进程结果Queue
多线程没有结果,将结果保存在Queue中,线程执行完后,从Queue中获取存储的结果1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26import threading
import time
from queue import Queue #定义一个模块,在小写q模块导入大写Q
def job(l,q):
for i in range(len(l)): #这边的l是一个列表,len(l)就是列表的长度,即个数
l[i] = l[i]**2 #列表的值的平方
q.put(l) #多线程调用的函数不能用return返回值
def multithreading():
q = Queue() #q中存放返回值,代替return的返回值
threads = [] #线程列表
data = [[1,2,3],[3,4,5],[4,4,4],[5,5,5]]
for i in range(4): : #定义四个线程
t = threading.Thread(target=job, args=(data[i], q)) #Thread首字母要大写,被调用的job函数没有括号,只是一个索引,参数在后面
t.start() #开始线程
threads.append(t) #把每个线程append到线程列表中
for thread in threads: #分别join四个线程到主线程
thread.join()
results = [] #定义一个空的列表results,将四个线运行后保存在队列中的结果返回给空列表results
for _ in range(4):
results.append(q.get()) #q.get()按顺序从q中拿出一个值
print(results)
if __name__ == '__main__': #if __name__ == '__main__'的意思是:当.py文件被直接运行时,if __name__ == '__main__'之下的代码块将被运行;当.py文件以模块形式被导入时,if __name__ == '__main__'之下的代码块不被运行。
multithreading() #多线程运算函数
GIL不一定有效率
Python 的设计上, 有一个必要的环节, 就是 Global Interpreter Lock (GIL). 这个东西让 Python 还是一次性只能处理一个东西。
这时候用多进程运算会卡。
线程锁
Lock1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27import threading #导入线程标准模块
def job1():
global A, lock #lock的函数
lock.acquire() #开始lock,job2不会接触job1的程序
for i in range(10):
A += 1
print('job1', A)
lock.release() #关闭lock
def job2():
global A, lock
lock.acquire()
for i in range(10):
A += 10
print('job2', A)
lock.release()
if __name__ == '__main__':
lock = threading.Lock() #一个大写一个小写
A = 0
t1 = threading.Thread(target=job1)
t2 = threading.Thread(target=job2)
t1.start()
t2.start()
t1.join()
t2.join()
多进程
添加进程
导入模块1
2
3
4
5
6
7
8
9
10
11
12import multiprocessing as mp #导入模块
import threading as td
def job(a,d):
print('aaaaa')
t1 = td.Thread(target=job,args=(1,2)) #job没有括号,有括号就是调用,这儿是引用这个目标罢了
p1 = mp.Process(target=job,args=(1,2))
t1.start()
p1.start()
t1.join()
p1.join()
完整代码:1
2
3
4
5
6
7
8
9import multiprocessing as mp
def job(a,d):
print('aaaaa')
if __name__=='__main__': #要在这个函数下面运行,不然报错,同时mac要在terminal下面
p1 = mp.Process(target=job,args=(1,2))
p1.start()
p1.join()
把值储存在queue里面
job本身没有返回值的原因才做这个1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19import multiprocessing as mp
def job(q):
res = 0
for i in range(1000):
res += i+i**2+i**3
q.put(res) # 放进q里面
if __name__ == '__main__':
q = mp.Queue() # q中存放返回值,代替return的返回值 。这是第一步
p1 = mp.Process(target=job, args=(q,)) #定义两个线程函数,用来处理同一个任务, args 的参数只要一个值的时候,参数后面需要加一个逗号,表示args是可迭代的,后面可能还有别的参数,不加逗号会出错
p2 = mp.Process(target=job, args=(q,))
p1.start()
p2.start()
p1.join()
p2.join()
res1 = q.get()
res2 = q.get()
print(res1+res2)
哪个有效率
1 | import multiprocessing as mp |
进程池
1 | import multiprocessing as mp |
map是Python的内置函数, 使用的方式如下;
list = map(func, iter)
其中, func是函数, iter是可迭代的序列。
它的功能是:将一个序列中的每一个元素应用传入的函数, 并返回一个包含所有函数调用结果的一个列表.
共享内存
共享内存 shared memory,不能多进程分享全局变量1
2
3
4
5import multiprocessing as mp
value1 = mp.Value('i', 0) # 形式 , 内容
value2 = mp.Value('d', 3.14)
array = mp.Array('i', [1, 2, 3, 4]) # 整数,一维列表
进程锁
Lock,还是要先定义共享内存1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20import multiprocessing as mp
import time
def job(v, num):
for _ in range(5):
time.sleep(0.1) # 暂停0.1秒,让输出效果更明显
v.value += num # v.value获取共享变量值
print(v.value, end="")
def multicore():
v = mp.Value('i', 0) # 定义共享变量
p1 = mp.Process(target=job, args=(v,1))
p2 = mp.Process(target=job, args=(v,3)) # 设定不同的number看如何抢夺内存
p1.start()
p2.start()
p1.join()
p2.join()
if __name__ == '__main__':
multicore()
上门会抢夺进程资源,下面是lock1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21def job(v, num, l): # 需要将lock传入 第二步
l.acquire() # 锁住 第三步
for _ in range(5):
time.sleep(0.1)
v.value += num # 获取共享内存
print(v.value)
l.release() # 释放
def multicore():
l = mp.Lock() # 定义一个进程锁,第一步
v = mp.Value('i', 0) # 定义共享内存
p1 = mp.Process(target=job, args=(v,1,l)) # 需要将lock传入
p2 = mp.Process(target=job, args=(v,3,l)) #p2 基于p1已经完成的基础上再加3
p1.start()
p2.start()
p1.join()
p2.join()
if __name__ == '__main__':
multicore()
tkinker窗口
一个GUI界面,实现一个直观的窗口
label&button标签和按钮
- 导入tkinter模块
- 建立函数名
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32import tkinter as tk
window = tk.Tk() #对象都是要大写的
window.title('my window') #名字
window.geometry('200x100') #大小
# 这里是窗口的内容
var = tk.StringVar() # 这时文字变量储存器
l = tk.Label(window,
textvariable=var, # 使用 textvariable 替换 text, 因为这个可以变化
bg='green', font=('Arial', 12), width=15, height=2)
l.pack() # 固定窗口位置,place()某个点的值
# 添加按钮
b = tk.Button(window,
text='hit me', # 显示在按钮上的文字,还是要大写B
width=15, height=2,
command=hit_me) # 点击按钮式执行的命令,就是hit_ne的函数
b.pack() # 按钮位置
# 定义hit_me函数
on_hit = False # 默认初始状态为 False
def hit_me():
global on_hit
if on_hit == False: # 从 False 状态变成 True 状态
on_hit = True
var.set('you hit me') # 设置标签的文字为 'you hit me'
else: # 从 True 状态变成 False 状态
on_hit = False
var.set('') # 设置 文字为空
window.mainloop() #最后一步,不断刷新
输入输出文本框 entry 和 text
1 | import tkinter as tk |
Listbox,列表部件
1 | import tkinter as tk |
选择按钮
1 | import tkinter as tk |
Scale尺寸
可以拉动,返回的是一个数字1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17import tkinter as tk
window = 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): #这个有默认的返回值,所以加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()
参数from_=5,to=11的意思就是从5到11,即这个滚动条最小值为5,最大值为11(这里使用from_是因为在python中有from这个关键词)
参数orient=tk.HORIZONTAL在这里就是设置滚动条的方向,如我们所看到的效果图,这里HORIZONTAL就是横向。要加tk
参数length这里是指滚动条部件的长度,但注意的是和其他部件width表示不同,width表示的是以字符为单位,比如width=4,就是4个字符的长度,而此处的length=200,是指我们常用的像素为单位,即长度为200个像素
参数resolution=0.01这里我们可以借助数学题来理解,我们做的很多数学题都会让我们来保留几位小数,此处的0.01就是保留2位小数,
showvalue=0显示的就是效果图,上方无结果显示,如果改为showvalue=1
参数tickinterval设置的就是坐标的间隔,此处为tickinterval=2,
checkbutton 勾选
和radiobutton类似
重点就是参数onvalue和offvalue的值,传入variable里面,同时定义传入的var是IntVar()的函数1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30import tkinter as tk
window = 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()
Canvas 画布
1 | import tkinter as tk |
菜单栏 menubar
1 | import tkinter as tk |
Frame 框架
1 | import tkinter as tk |
Message弹窗
tk.messagebox.showinfo(title=’’,message=’’)#提示信息对话窗
tk.messagebox.showwarning()#提出警告对话窗
tk.messagebox.showerror()#提出错误对话窗
tk.messagebox.askquestion()#询问选择对话窗
注意是小写1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19import tkinter as tk
import tkinter.messagebox
window = 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, False
print(tk.messagebox.asktrycancel(title='Hi', message='hahahaha')) # return True, False
print(tk.messagebox.askokcancel(title='Hi', message='hahahaha')) # return True, False
print(tk.messagebox.askyesnocancel(title="Hi", message="haha")) # return, True, False, None
tk.Button(window, text='hit me', command=hit_me).pack()
window.mainloop()
pack,grid,place放置位置
pack(),参数是side1
2
3
4tk.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')#右
grid
接下里我们在看看grid(), grid 是方格, 所以所有的内容会被放在这些规律的方格中.
以上的代码就是创建一个四行三列的表格,其实grid就是用表格的形式定位的。这里的参数 row为行,colum为列,padx就是单元格左右间距,pady就是单元格上下间距。1
2
3for i in range(4): #行
for j in range(3): #列
tk.Label(window, text=1).grid(row=i, column=j, padx=10, pady=10) #内部拓展,ipadx
place
再接下来就是place(), 这个比较容易理解,就是给精确的坐标来定位,如此处给的(20,10),就是将这个部件放在坐标为(x,y)的这个位置 后面的参数anchor=nw就是前面所讲的锚定点是西北角。1
tk.Label(window, text=1).place(x=20, y=10, anchor='nw')
登录窗口
https://morvanzhou.github.io/tutorials/python-basic/tkinter/3-03-example3/1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94import tkinter as tk
from tkinter import messagebox # import this to fix messagebox error
import pickle
window = 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] = np
with 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()
pickle模块
pickle 是一个 python 中, 压缩/保存/提取 文件的模块. 最一般的使用方式非常简单. 比如下面就是压缩并保存一个字典的方式. 字典和列表都是能被保存的.1
2
3
4
5
6
7
8
9
10
11
12
13
14import pickle
a_dict = {'da': 111, 2: [23,1,4], '23': {1:2,'d':'sad'}}
# pickle a variable to a file
file = open('pickle_example.pickle', 'wb') #wb 是以写的形式打开
pickle.dump(a_dict, file) #装载的是a_dict,装在flie里面(固定在文件列表里面),就有一个pickle_example.pickle
file.close()
# reload a file to a variable
with open('pickle_example.pickle', 'rb') as file: #rb 是读的形式打开,with不用考虑关闭file.close()
a_dict1 =pickle.load(file)
print(a_dict1)