文章目录
- Python补充内容
- 函数
- 可选参数
- 调用自己
- 跨文件调用
- Python标准库
- 列表、元组与字典
- 列表
- 列表的索引
- 获取列表的长度
- 列表的修改
- 列表的增减
- 拼接与切片(截取)
- 元组
- 字典
- 字符串的拼接和切片
- for循环
- 实现游戏
- 需求
- 分析
上一节练习示例代码:
#猜大小.py
import random
num = random.randint(1,1000)
times = 0
while True:
n = input("猜大小(%d-%d):"%(1,1000))
n = int(n)
times += 1
if n<num:
print("猜小了。")
elif n>num:
print("猜大了。")
else:
print("猜对了!")
print("总共猜了%d次"%(times))
break
只有文字和疼痛的手指,一点都不快乐。不过没关系,马上我们就要进行一项图像相关的经典游戏:贪吃蛇!我们将会在两个平台完成这个游戏:电脑上和手机上。
Python补充内容
拾遗补阙
学习Python的过程中,你会逐渐敲开三扇大门:循环、函数、类。
现在我们来敲开第二扇。
函数
初中你接触过这样的函数:
到了高中变成了这个样子:
不变的是:左边是结果,右边是公式(函数),其中为自变量。
在Python中这样定义函数:
def f(x):
return 2*x+3
a = f(2)
print(a)
def
关键字用来定义函数,在上面的示例中f
为函数名,其后面括号里的x
就是自变量,我们称为参数。
return
关键字表示要返回(得到)的结果。
如同上面中学的公式一样:a = f(2)
左边是结果,右边是函数,不过我们给自变量代入了一个值,函数就会得到一个唯一的结果,print
这个结果:
7
试试复杂点的:
def CircleArea(r):
pi = 3.1415926
S = pi*r**2
return S
print(CircleArea(2))
没有晕头转向吧?搞明白上面实现了什么吗?
不要被circleArea
这么长的名字唬住了,它只是个函数名,和上面的f
没什么两样。
函数内定义了一个变量pi
——泼艾。还有一个变量S,它的值是它后面式子的值。
S=pi*r**2
完成了初中求圆面积公式:。
然后return
,返回了结果S,在最后我们传入函数一个值,得到了一个结果:
12.5663704
是不是愈发觉得Python是个不错的计算器了?
你可以尝试实现其他数学公式,但是不要把它带到考场上去。
我们可以给函数传入多个变量或者不传入参数,也可以让函数不返回值:
def Say():
print("我不需要参数")
def SayTxt(txt):
print("我需要一个参数:",txt)
def SaySay(a,b,c):
print("我需要三个参数:",a,b,c)
Say()
SayTxt("一个参数")
SaySay("一个参数","两个参数","千万个参数")
print(Say())
运行结果:
我不需要参数
我需要一个参数: 一个参数
我需要三个参数: 一个参数 两个参数 千万个参数
None
注意最后一行的None
,因为Say
函数没有写return
,Python就默认给了它一个返回值:None
,表示:没有、什么都不是。注意,None
是Python的一个关键字,不是字符串。
Python的一般是从上到下顺序执行,遇到循环再跳转回去,遇到函数跳到到函数里。
def
关键字只是定义函数,不会执行具体的函数。但使用函数名+括号(如f(2)
)便调用了函数,Python会跳到函数内执行,直到遇到return
或者执行完了再跳出函数。
可选参数
def f(a,b="B"):
print(a,b)
f("A")
f("A",b="C")
A B
A C
调用自己
def boom():
print("爆炸吧现冲!")
boom()
boom()
如果你尝试运行上面的代码,你就会被同一句话刷屏,因为函数不断地调用自己永远不会返回值。
看看下面这段代码实现了什么?
def factorial(n):
if n>1:
n = n * factorial(n-1)
return n
a = factorial(4)
print(a)
如果传入的n大于1if n>1
,就让n等于n乘以factorial(n-1)
的返回值,又进入判断n-1
是否大于1。
实际上这段代码实现的就是阶乘,factorial(4)
其实结果就是4*3*2
等于24。
这种调用方式称为函数的迭代。
跨文件调用
我们来做这样一件事:
创建一个新脚本fun.py
:
def f(x):
return 2*x+3
没错,就是上面我们写的第一个函数。
然后在相同目录下创建另一个新脚本,随便起个文件名,但两个脚本要在同一个文件夹里。
在新脚本里运行这段代码:
import fun
a = fun.f(2)
print(a)
7
我们还可以只导入函数f
:
from fun import f
a = f(2)
发现了什么?
在其他脚本里通过关键字import
导入,就可以像直接在fun.py
里直接调用f
函数一样使用函数。
回顾一下上次练习中的游戏猜大小的部分代码:
import random
num = random.randint(1,1000)
当然我们也可以只导入randint
:
form random import randint
num = randint(1,1000)
你可以理解为random是Python自带的一个隐形的文件,你导入了它,就可以使用它里面的函数。实际上你可以在你的Python安装目录下的lib
文件夹里可以找到random
文件。
什么,你不知道Python的安装目录?
打开cmd,输入咒语where python
,回车,你就找到了。
不不,不要看着路径一下一下点进目录,直接拷贝你的python目录(注意是目录,不包括最后的python.exe),在cmd中接着输入start 粘贴你的目录
,像这样:
回车,看看发生了什么。
cmd真是个好东西,我们以后可以用它来搞事情,当然是使用Python调用cmd。
Python标准库
像random这样由函数或类组成的包,在Python里称之为库。
python自带了很多这种库,被称为python标准库。而你上面写的fun.py
可以当作非标准库。
在https://docs.python.org/zh-cn/3/library/index.html里可以看到所有python的标准库,之后我也会陆续介绍一些常用的标准库。
这里介绍其中一个标准库:time
:
import time #导入time库
help(time.time) #使用help函数获得time.time的帮助信息
如果你英语不错的话可以看懂运行结果,不然就和我一样借助词典:
Help on built-in function time in module time:
time(...)
time() -> floating point number
Return the current time in seconds since the Epoch.
Fractions of a second may be present if the system clock provides them.
floating point number
告诉我们这个函数返回是一个浮点数。
Return the current time in seconds since the Epoch.
翻译过来就是:返回自Epoch到现在以来以秒为单位的时间。
Epoch是1970.01.01 00:00:00 这一时刻。
print出来看看:
import time
print(time.time())
1583914783.291243
你的值应该比我的大,除非你穿越而来在我写这一节前跑了上面这段程序,或者你电脑坏了。
注意使用help时用的time.time
,而print时是time.time()
,函数没括号代表着是函数它本身,函数后有括号则表示执行函数返回结果。
之后我们会用到各种各样的库,万一我抽风没把库讲清楚,你可以借助help函数本地查询用法。
而time标准库意义重大,这代表我们掌握一个伟大的工具:时间!
还记得最开始的手指抽筋模拟器吗,这里我要给出它的第一次升级版本:
#手指抽筋模拟器基础语法升级版.py
import time
num = 0
input("你点我啊!")
start = time.time()
while time.time()-start <= 10:
input()
num += 1
print("啊啊啊~")
print("10秒内你点击了%d次"%(num))
while True:
input()
input("你点我啊!")
等待玩家开始点击。
start = time.time()
记录开始时间。
while time.time()-start <= 10:
当时间过去的时间小于等于10,就继续循环,否则结束循环。
最后的又写了一个循环,是为了双击文件执行时,窗口不会在十秒结束循环后自动关闭。
列表、元组与字典
我们在穿过一扇门时就会看见另一扇门
列表
a = [1,"2",3.456]
Python中列表是由中括号括起来的元素的集合,元素可以是任何数据,包括函数和之后要提到的类。
列表的索引
print(a[1])
print(a[-1])
运行结果:
2
3.456
列表后面中括号来索引元素,中括号里的整数代表第几个元素。注意:在编程的世界里,第一个元素的索引是0,以此类推,所以a[1]
的结果是"2"
。a[-1]
索引的是倒数第一个元素,倒数第二个是a[-2]
,依次类推。
有点绕,多试试再继续下面的内容。
获取列表的长度
a = [1,2,3]
print(len(a))
3
列表的修改
a[1]=233
print(a)
[1, 233, 3.456]
列表的增减
a = []
a.append(1)
a.append(2)
a.append(3)
print(a)
[1, 2, 3]
a = []
创建了一个空列表。
你注意到这里使用了.
操作符,好像a
是个上面函数中说的文件似的,但它确实是自己写的一个变量名啊!
Python赋予了列表类似文件中的函数效果,实际上不管是文件还是列表,python都把它当作一个类。之后我们回详细解释类,现在你只需要有这个概念就行了。
后面的append
函数进行的是增加元素操作,它会把新元素添加在列表的最后。
在指定位置插入:
a = [1,2,3,4]
a.insert(2,2.5)
print(a)
[1, 2, 2.5, 3, 4]
a.insert(2,2.5)
在索引为2的元素前面插入了新元素2.5
。来,和我一起依次数索引:0,1,2,3 。
删除指定索引的元素:
a = [1,2,3,4]
a.pop(2)
print(a)
[1, 2, 4]
直接删除一个元素:
a = [1,2,3,2,3,4]
a.remove(2)
print(a)
[1, 3, 2, 3, 4]
注意:remove只会删除第一个匹配的值。
拼接与切片(截取)
a = [1,2,3]
b = [4,5,6]
c = a + b
d = a * 2
print(c)
print(d)
[1, 2, 3, 4, 5, 6]
[1, 2, 3, 1, 2, 3]
加法把两个列表元素连起来,乘法把元素个数翻倍,其它算术符号就不要试了,否则列表会说:“我们没有结果”,然后抛给你一推错误。
接下来特别重要,将来你会不断地尝试不断地疑惑列表的切片(就像我一样):
a = [1,2,3,4]
print(a[1:3])
print(a[2:])
print(a[:-2])
[2, 3]
[3, 4]
[1, 2]
中括号里[x:y]
由冒号隔开的两个索引x、y切割了列表,它会返回列表索引x(包括x)到索引y(不包括y)之间的元素构成的新列表。
如果不写x,默认就是0,不写y,默认就是-1 。
多试一试,理解一下再继续。
元组
a = (1,"2",3.456)
元组是由小括号括起来的元素集合,它拥有和列表相同的操作方式,但是一点不同的是,元组一旦创建不能再修改里面的元素,如果你试图修改或增减元组:
a[1] = 5
Traceback (most recent call last):
a[1] = 5
TypeError: 'tuple' object does not support item assignment
a.append(5)
Traceback (most recent call last):
a.append(5)
AttributeError: 'tuple' object has no attribute 'append'
它会无情地抛出一推错误,顺便测试一下你的英语水平。
总结:元组不能修改增减元素,但可以向列表一样索引拼接和截取。
字典
a = {"狗":"dog","猫":"cat",1:"one","one":1}
print(a["狗"])
print(a[1])
dog
one
字典是由花括号括起,里面是一对对键值(key:value),键值对之间没有顺序,我们要通过键(key)来查询值(value)。
可以这样添加新的键值对:
a[2] = "two"
字典里的键是唯一的:
a = {}
a["two"] = 2
a["two"] = "兔"
print(a["two"])
兔
删除操作:
del a["two"] #删除指定键值对
a.clear() #清空字典
del a #删除字典
字符串的拼接和切片
a = "Hello "
b = "World!"
print(a[1])
print(a+b)
print(a+'\n'+b)
e
Hello World!
Hello
World!
a = "Hello World!"
print(a[2:5])
print(a[:-3])
llo
Hello Wor
可以看到,字符串的拼接和切片方式与列表完全一样。
for循环
Python提供了for
……in
来遍历(依次获取)列表或元组:
a = [1,2,3,4]
for b in a:
print(b)
print("结束")
1
2
3
4
结束
上面这段代码依次从a
中拿取元素赋值给变量b
,直到a
中的元素拿完。
for
和while
一样可以使用break
和continue
。
in
也可以用作条件判断,表示“在……里”,搭配not
关键字表示“不在……里”:
a = [1,2,3]
print(1 in a)
print("2" in a)
print("3" not in a)
True
False
True
实现游戏
我们已经学了很多Python的知识,但我们要做一个贪吃蛇游戏,还是不知道从何开始。
怎么把像素显示在屏幕上?
有人把像素显示在屏幕上的代码写成了一个个库,我们只要import
一下就可以拿来用了。
电脑端有个不错游戏库叫做Pygame,但是它不能直接用在手机上。
手机上有个图像库叫做kivy,也可以用在电脑上,但是大量用到类,这个我们还没深入了解,冒然深入必将引起不快,所以我们先用Pygame实现游戏,构建游戏的逻辑明白后,不管用什么库都可以很快地重写一遍。
需求
- 一条由方块组成的蛇,每吃掉一个“苹果”方块,身体便增长一格。
- 每吃掉一个“苹果”便再随机生成一个新的“苹果”。
- 玩家用键盘控制蛇的移动方向,蛇一格一格地移动。
- “蛇头”碰到苹果便为“吃到”,碰到屏幕边缘“墙壁”或者自己的身体便游戏结束。
- 游戏结束后给出分数(吃掉的苹果数)。
分析
- 每个方块实际上是个位置信息,比如
[x,y]
。 - 一条蛇有很多块,我们可以存在一起:
[[x0,y0],[x1,y1],[x2,y2]]
。 - 需要判断是否吃到苹果或者自己、需要显示分数,可预见的要使用条件判断和函数
- 每过半秒或多长时间刷新一下画面,让蛇移动一格。需要用到循环。
貌似我们已经学了上面分析中需要用到的所有东西,下一节我们将正式开始游戏之旅!