宇宙无垠,知识无尽。而我卑微。
目录
首先,这是一篇入门级Python学习帮助,可以帮助刚刚接触这一语言的同学了解基本语法。为了使文章浅显易懂,本文不加入较深层次的原理,讲解也不十分严肃,不可以作为一篇标准的学习指导。但仅为实现一些功能,完全可以参考。本文旨在激发python学习者对python的学习热情,和展示python可以实现的一部分功能。
在文章开始部分,考虑到使用工具不同或从未进行过实际操作的同学,会有较多图片。而后,便更多的是代码文本。
python的工具
在学习之前,你当然需要有相关工具。笔者所用版本为3.5.3,所用工具为Python自带的IDLE和shell。笔者觉得,这非常适合初学者学习python。关于如何下载,网上有许多非常好的方法,故不在此赘述。
python的代码创建有两种方式。一种是交互式的,一种是文件式的。
本文中,
交互式界面的代码风格是这样的:
>>>
>>>
>>>
文件式的代码风格是这样的:
实际情况是这样的:
<交互式界面与文件式界面>
背景颜色,代码颜色,字体以及大小都是可以自己手动调节的。
在交互式界面,输入一行代码,按下回车,就会运行一次,有返回结果的就会显示返回结果,或者报错。
而文本式界面,输入代码之后,需要保存文本,再点击运行才会运行并显示结果。
变量与基本数据类型
变量的定义
接下来我们讲一下最基本的语法,变量的定义和变量的一些简单的类型讲解。
在python中,输入一个变量并初始化时,输入
<变量名>=<初始值>
这时,即完成了变量的定义。
注意到,在变量定义的过程中,没有对变量的类型进行声明,那么这是一个什么类型的变量呢?
在python中,定义变量时,会自动根据变量的内容更改变量的类型。上文中的a和b都是数字类型。因为他们存储的值是数字。具体而言,它是整数类型。可以使用type(<变量名>)来查看变量的类型。
在python中,变量的名字不能以数字和一些特殊符号开头,否则会报错。在此条件下,可以由英文字母,数字,汉字和下划线等组成。
为了使变量的含义更为清晰,我们应当为变量起一个合适的名字。
尽管朱丽叶说:“名字又有什么关系?把玫瑰叫做别的,它仍旧芳香。”
可事实上名字还是很重要的。
数字类型
最简单的变量类型即是数字类型。如上图,a,b两个变量就是数字变量。
数字类型具体分为整数,小数和复数。
整数可以用二进制,八进制,十进制和十六进制来表示。本文只介绍十进制。他们之间是可以相互转换的。
小数即是带有小数点的数字。比如6.6,6.0。注意6和6.0不一样,前者是整数,而后者是小数。即小数必须带有小数点。
还有复数类型,以a+bj的形式表示。与数学中不同的是,虚数单位不是i而是j。
复数可以用z.real() 和z.imag()来获取实部和虚部。
数字类型还可以用科学计算法表示。
如2e3或2E3都表示2乘10的三次方,即整数2000。
数值运算操作符
操作 | 描述 |
---|---|
a+b | a与b之和 |
a-b | a与b之差 |
a*b | a与b之积 |
a**b | a的b次方 |
a/b | a与b之商,结果为小数 |
a//b | a与b之商,结果为整数 |
a%b | a与b之商的余数,也称作求模运算 |
-a | a的相反数 |
数值运算函数
函数 | 描述 |
---|---|
abs(a) | 返回a的绝对值 |
max(a1,a2,a3…an) | 返回n个数字中的最大值 |
min(a1,a2,a3…an) | 返回n个数字中的最小值 |
divmod(a,b) | 返回两个数据,a//b和a%y |
pow(a,b)和pow(a,b,c) | a**b,(a**b)%c |
round(a)和round(a,b) | 保留a的整数,或b个小数位的小数 |
布尔类型
布尔类型只有两个不同值,True和False。要注意第一个字母大写。
当进行条件判断时,表达式的值就会是布尔类型
这就属于一种逻辑运算。而逻辑运算在后面的文章中会有更详细的叙述。
字符串类型
字符串十多个字符的有序组合。简单来说,就是一串字符。
字符串可以分为单行字符串和多行字符串。单行字符串用一对引号输入,多行字符串用一对三引号输入。
有关字符串的操作在后文会有更详细的叙述。在这里先简单介绍两个小技巧。
第一个是两个字符串可以用简单的方法连接。
如图,用一个小小的加号,即可创建一个副本,将字符串按左右顺序连接起来。
连接时要注意左右顺序是有意义的,颠倒过来就是另一个字符串了。
与此无关但是十分有趣的是,str4与str5都十分有意境,读者认为,哪句更好呢
第二个,字符串有一个简单的重复方法。
就好像一个字符串和一个整数n相乘。这样即可重复一个字符串n次。
第三个字符串操作符是 in,这也是一个保留字。如果一个元素在字符串中,则返回True,否则返回False
字符串还有一个基本操作叫做索引。
字符串是一个有序结构,那么他的每一个元素都可以按照特定顺序访问位置。字符串的顺序有两种,一种是正序,第一个元素从0开始计数,到最后一个元素。另一种是逆序,最后一个元素从-1开始计数,反向排到第一个元素。这些数字被称为下标。索引就是依照下表访问字符串的指定元素。
而字符串的切片,就是索引字符串的一段,被形象化的称为切片。
如图,切片有两种,一种是指定范围,取得包括左边界但不包括右边界的区间内所有元素。另一种是指定的“跨越长度”,即索引间隔多长,取得间隔上的元素。
字符串和列表类型
字符串
在前文,我们已经粗略地介绍过字符串,分为单行字符串和多行字符串,以及字符串连接,重复,和索引以及切片。
接下来介绍一些内置的处理字符串的函数
函数 | 描述 |
---|---|
len(s) | 求字符串的长度 |
str(s) | 将任意类型数据转化为字符串 |
chr(x) | 返回整数unicode编码x对应的单字符 |
ord(x) | 返回单字符x表示的unicode编码 |
>>> str1='python'
>>> len(str1)
6
>>> a=123
>>> type(a)
<class 'int'>
>>> str2=str(a)
>>> str2
'123'
>>> type(str2)
<class 'str'>
>>> chr(1000)
'Ϩ'
>>> ord('s')
115
除了这些函数之外,python内部还有许多方法用来处理字符串。方法与函数类似,但使用方法不同。
方法 | 描述 |
---|---|
str.isalnum() | 判断字符串是否有且仅有英文字母或数字 |
str.isalpha() | 判断字符串是否有且仅有英文字母 |
str.isdigit() | 判断字符串是否有且仅有数字 |
str.isspace() | 判断字符串是否有且仅有空格 |
str.islower() | 判断字符串是否有且仅有小写字母 |
str.isupper() | 判断字符串是否有且仅有大写字母 |
str.startswith(s) | 判断字符串是否由字符串s作为开头 |
str.endswith(s) | 判断字符串是否由字符串s作为结尾 |
str.upper() | 返回字符串的副本,将字符串中的字母全部换为大写 |
str.lower() | 返回字符串的副本,将字符串中的字母全部换为小写 |
str.count(s) | 返回字符串中字符串s出现的次数 |
str.split(x) | 将字符串以字符串x进行分割,结果以列表形式返回。默认以空格分割 |
>>> str_num='24601'
>>> str_alpha='sin'
>>> str_alpha_num='Now bring me prisoner 24601.'
>>> str_blank=' '
>>> str_num.isalnum()
True
>>> str_num.isalpha()
False
>>> str_num.isdigit()
True
>>> str_num.isspace()
False
>>> str_alpha.islower()
True
>>> str_alpha.isupper()
False
>>> str_blank.isspace()
True
>>> str_alpha_num.split()
['Now', 'bring', 'me', 'prisoner', '24601.']
除了字符串,这里还要介绍一种类型叫做列表。刚刚已经提到str.split()方法返回的是一个列表,那么列表是什么呢?
列表是一种包含零个或多个元素的有序序列,是序列类型。列表可以进行元素的增,删,改,查,等操作。列表类型用方括号表示。list()
函数可以生成空列表,或将一个数据改为列表类型。
>>> list1=[] #定义一个空列表
>>> print(list1)
[]
>>> list1=list('白云千载空悠悠') #将字符串转为列表
>>> list1
['白', '云', '千', '载', '空', '悠', '悠']
>>> list1=[1,2,3] #初始化一个列表
>>> list1
[1, 2, 3]
>>> type(list1)
<class 'list'>
列表也有连接,重复,索引和切片这样的操作。
>>> list2=list('投我以木瓜')
>>> list3=list('报之以琼琚')
>>> list2+list3 #用加号将两个列表连接
['投', '我', '以', '木', '瓜', '报', '之', '以', '琼', '琚']
>>> list4=['#']*4 #重复符号四次作为四个元素
>>> list4
['#', '#', '#', '#']
>>> list4=['#'*4] #重复符号四次作为一个元素
>>> list4
['####']
>>> list2[0] #索引
'投'
>>> list2[0:4:2] #切片
['投', '以']
一些内置的函数可以用来对列表进行操作
函数 | 描述 |
---|---|
len(list) | 求列表的长度 |
min(list) | 求列表中的最小元素 |
max(list) | 求列表中的最大元素 |
list(x) | 将x变为列表类型 |
使用min(),max()
这两个函数的前提是列表元素各类型之间可以进行比较,否则会报错
列表也有许多操作方法
方法 | 描述 |
---|---|
list.append(x) | 在列表后面加入一个元素x |
list.clear() | 清空列表 |
list.copy() | 返回一个新列表,与原列表内容相同 |
list.count(x) | 计算列表中x出现的次数 |
list.extend(x) | 将x连接在列表后面 |
list.insert(pos,x) | 在第pos位置插入x |
list.pop(i) | 弹栈,即读取并清除将第 i 项元素。无参数时,随机弹出 |
list.remove(x) | 将列表中的第一个x元素删除 |
list.reverse() | 翻转列表 |
list.sort() | 对列表进行排序 |
>>> list0=[]
>>> list0.append(6)
>>> list0.append(6)
>>> list0
[6, 6]
>>> list0.count(6)
2
>>> list0.extend([5,4])
>>> list0
[6, 6, 5, 4]
>>> list0.insert(3,7)
>>> list0
[6, 6, 5, 7, 4]
>>> list0.pop()
4
>>> list0.pop(2)
5
>>> list0.remove(6)
>>> list0
[6, 7]
>>> list0.reverse()
>>> list0
[7, 6]
>>> list0.sort()
>>>> list0
[6, 7]
需要注意的是,并不能像普通变量一样,通过直接将一个列表赋值给另一个变量名来复制列表:
>>> list1=['old']
>>> list2=list1
>>> list2
['old']
>>> list1.clear()
>>> list1
[]
>>> list2
[]
通过以上代码可以看出,这不过是给原有列表加了一个额外的名称,并没有将它复制。
若要复制一个列表,需要使用list.copy()
>>> list1=['滚滚长江东逝水']
>>> list2=list1.copy()
>>> list1.clear()
>>> list2
['滚滚长江东逝水']
>>> list1
[]
输入和输出
输入
输入时,用input()函数,可以输入一个字符串并传递给变量。因为一切输入都被当作字符串了,故一切输入用input接受都是合法的。input()内可以输入提示性文字。
>>> a=input('Please enter a integer:')
Please enter a integer:123
>>> a
'123'
>>> type(a)
<class 'str'>
>>>
>>> str1=input('请输入“姑苏城外寒山寺”的下一句:')
请输入“姑苏城外寒山寺”的下一句:夜半钟声到客船
>>> str1
'夜半钟声到客船'
eval()可以用来处理字符串,去掉其外层一层引号与input()结合,可以将input()接受的输入进行运算后再接收.这样便可以方便地输入一个数字
>>> num=eval(input('Enter a number:'))
Enter a number:55
>>> num
55
>>> type(num)
<class 'int'>
>>>#说明输入的不是字符串
上面代码中的井号表示注释,#后面的文本都会被当做注释
输出
输出时,使用print()函数。
>>> print(5+3)
8
>>> num=10
>>> print(num)
10
>>> print(num+10)
20
>>> str1='不废江河万古流'
>>> print(str1)
不废江河万古流
还可以在输出中插入变量,控制输出
>>> a=3
>>> b=4
>>> print('%d和%d的和是%d'%(a,b,a+b))
3和4的和是7
也可以填入多个参数输出
>>> a=3
>>> b=4
>>> print(a,'和',b,'的差是',a-b)
3 和 4 的差是 -1
注意print()函数默认会在最后输出一个换行。实际上其内部有一个参数控制结尾输出字符,默认情况下是输出’\n’即换行。可以改变这个参数来控制输出。
使print()的参数end为空,即没有任何追加输出。
程序的控制结构
概述
任何程序都由三种基本结构组成。顺序结构,分支结构和循环结构。
正常情况下,python代码都是从第一行开始,逐行向下运行,这就是顺序结构。显然,许多问题不能仅由顺序结构完成。
分支结构
分支结构是程序根据条件判断结果而选择不同执行路径的一种运行方式。最基础的分支结构是二分支结构。即根据判断条件产生的结果选择是否进行这条路径。
首先介绍条件的判断。条件是一个逻辑表达式,可以产生布尔类型的值,即真或假,True或False。它可以由多个小条件组成。
判断条件和条件组合需要用到python的关系操作符
关系操作符
操作符 | 含义 |
---|---|
> | 大于 |
< | 小于 |
== | 等于 |
>= | 大于等于 |
<= | 小于等于 |
!= | 不等于 |
>>> 5>10
False
>>> 5<10
True
>>> 5!=10
True
还可以使用python的保留字and,or,not连接多个条件,and 表示逻辑与,or表示逻辑或,not表示逻辑非。
>>> 5>3 and 5<10
True
>>> 5>0 or -1>0
True
>>> not 5>0
False
单分支结构
最基本分支结构是
if<条件>:
<代码块>
如果条件为真,则会执行<代码块>。否则跳过,继续执行下一部分。
要注意条件后的冒号,和下一行行首的缩进。缩进在python中有严格的使用方法。相同缩进的代码被认为是属于同部分。如分支结构中的一个代码块有相同的缩进。
a=3
b=4
if a>b:
print('a>b')
这一代码的结果应当是无输出的,因为条件判断的结果为假。这样显然不够完美。我们继续向下看。
二分支结构
if<条件>:
<代码块一>
else:
<代码块二>
在这样的分支结构中,首先会进行条件判断,若为真,则执行<代码块一>,否则会执行<代码块二>。
a=3
b=4
if a>b:
print('a>b')
else:
print('a<b')
这样,前面的例子就有了相应的输出。
但有时情况会更为复杂。
多分支结构
多分枝结构的使用方法如下
if<条件一>:
<代码块一>
elif<条件二>:
<代码块二>
else:
<代码块三>
a=3
b=3
if a>b:
print('a>b')
elif a<b:
print('a<b')
else:
print('a==b')
输出结果是
>>>a==b
循环结构
除了分支结构外,还有循环结构,也十分常用。在遇到大量重复劳动时,即可使用循环,更为便捷地达到目的。
python的循环结构分为两种,一种是遍历循环,一种是无限循环。
遍历循环
遍历循环的使用方法如下:
for <循环变量> in <遍历结构>:
<语句块>
这里的遍历结构中,常用的是range()函数。举个例子,大家可以明显看出它的效果。
>>> for i in range(6):
print(i,end=' ')
0 1 2 3 4 5
>>> for i in range(1,7):
print(i,end=' ')
1 2 3 4 5 6
实际上,在遍历过程中,通过循环变量依次提取遍历结构中的各个元素,然后进行接下来的操作。
在第一个例子中,我们可以认为,range(6)产生了一个遍历结构,它包含0,1,2,3,4,5这六个数字。但它并非一个简单的类型。对于初学者,我们目前不需要了解他具体是什么, 我们只要知道,在循环中,这个结构之内的元素可以被依次提取出来,并使用即可。
在第二个例子中,从结果上看range(1,7)产生了另一个遍历结构,它包含1,2,3,4,5,6六个数。1是起点,包含在内,7是终点,不包含在内。
字符串也是一种遍历结构。
>>> str1='长风破浪会有时'
>>> for c in str1:
print(c,end='')
长风破浪会有时
前面我们还介绍了列表类型,这也是一种遍历结构。
>>> list1=list('野径云俱黑,江船火独明。')
>>> for c in list1:
print(c,end='')
野径云俱黑,江船火独明。
对于字符串和列表的遍历,并非仅仅可以将他们简单输出而已。
通过综合利用这两个类型,我们可以进行一些较为复杂的文本处理。
无限循环
使用方式如下
while 【条件】:
【语句块】
当【条件】为真时,该循环便可以进行,否则退出。
例如
>>> i=0
>>> while i<10:
print(i,end='')
i+=1
0123456789
>>> i=1
>>> while True:
print(str(i)*i)
i+=1
if i==5:
break
1
22
333
4444
在使用循环结构前,应考虑使用哪种循环。一般而言,知道循环次数,则使用for知道终止条件,则使用while。当然,实际上,在知道循环次数时使用while也完全没有问题
在终止条件已知时,用for同样无可厚非。在前面的例子中即可看出这一点
一个有趣的实验
在学习了这么多知识后,是时候做一些尝试了。
尝试一下,输出以下图形
*
**
***
****
*****
相信这种类型的问题,在我们初学语言时,都遇到过。如果你从未遇到过,那么你现在遇到了。在逻辑上,最简单的方法莫过于:
print('*')
print('**')
print('***')
print('****')
print('*****')
当然,这样的代码运行后即可显示要求图形。但若要求输出图形依此规律有一千行呢?显然有更好的方法。简单分析我们即可发现,从第一行到第四行,每一行输出了与行数相等数量的*。这是一种有规律的重复劳动。自然而然地,我们想到了循环。那么,我们只需要加入一个循环即可输出任意数量行的图形
刚才我们已经发现,每一行输出与行数相等数量的星号,而一共输出了五行。那么我们首先需要一个循环,从1到5,控制行数,在需要第二个循环,重复输出当前行标数量的星号。
代码如下:
for i in range(1,6):
for j in range(i):
print('*',end='')
print()
结果如下
*
**
***
****
*****
之前,我们提到过利用星号的字符串重复方法。可以借此改进我们的代码,使之更加简洁。
for i in range(1,6):
print('*'*i)
这个代码和上述代码有同样的功能
但为了增强逻辑,下文若干例题不再使用此方法。
进一步,尝试输出如下图形:
****
***
**
*
首先分析这个问题,我们列一个表格
行标 | 符号数量 |
---|---|
1 | 4 |
2 | 3 |
3 | 2 |
4 | 1 |
我们发现总有这样一个等式:行标+符号数量=5.实际上,这个五,等于行数+1,即行标+符号数量=行数+1.那么,符号数量=行数+1-行标
如此,这个问题的解决方法呼之欲出
for i in range(1,6):
for j in range(1,6+1-i):
print('*',end='')
print()
这样,输出的结果便可以符合要求。
现在我们换一个要求,输出下面图形
*
**
***
****
同样的,我们先分析这个问题。
12345
1 *
2 **
3 ***
4 ****
相信你的一双慧眼已经发现了其中的玄机。在上一题中,要求输出星号的地方,变为了空格。相反,原本没有输出的地方,要输出星号。这就需要我们辨别两种不同位置。自然而然地,我们想到了分支结构。只要在循环内,加入if-else即可。
blank+i=5
blank=5-i
完成代码如下
for i in range(1,6):
for j in range(1,6):
if 1<=j<=6-i-1:
print(end=' ')
else:
print('*',end='')
print()
我们再提升一个难度,输出一个实心菱形,输出一个空心菱形
* *
*** * *
***** * *
*** * *
* *
这和前一个例子相似,我们只需要区分哪些地方输出星号,哪些地方输出空格即可。当然,你也可以将它分为上下两半分别输出。但这样,就降低了挑战的趣味。
老规矩,分析这两个图形。
12345 12345
1 * *
2 *** * *
3 ***** * *
4 *** * *
5 * *
应该想到,我们可以先输出第一个图形,再进行改进,即可输出第二个图形。不难发现,图形中心有一条对称轴,在这个对称轴左右的区间内输出符号,其余部分输
出空格即可。
需要注意一个细节,在前三行,星号逐渐变多,在后两行,星号逐渐变少。因此,我们需要先对行标进行分类,在每个分类下,再对输出区域的类型进行分类
for i in range(1,6): #输出一个实心菱形
for j in range(1,6):
if i<4:
if 3-i<j<3+i:
print('*',end='')
else:
print(end=' ')
else:
if 3-5+i<=j<=3+5-i:
print(end='*')
else:
print(end=' ')
print()
若要输出一个空心菱形,即只要输出菱形“边界”即可。
for i in range(1,6): #输出一个空心菱形
for j in range(1,6):
if i<4:
if 3-i+1==j or j==3+i-1:
print('*',end='')
else:
print(end=' ')
else:
if 3-5+i==j or j==3+5-i:
print(end='*')
else:
print(end=' ')
print()
到这里,我们的趣味小尝试先告一段落。实际上,我们还可以尝试一下输出平行四边形,金字塔,杨辉三角等图形,都是非常有趣的。
经过这些尝试,相信大家已经对前面的知识有更深的理解了。
而下一节,将介绍python中的一个更加有趣的模块。
turtle库
概述
turtle库是python自带的一个库,即标准库,用于进行图形绘制。绘制时,我们可以通过控制一个独特的画笔进行绘制。
使用前,需要使用保留字import对turtle库进行调用。
调用方式有多种
第一种
import turtle
调用后,即可使用turtle库函数。
使用时,用<库名>.<函数名>(参数列表)
如
turtle.showturtle()
需要为函数提供参数时,则要输入参数,否则会报错。
调用还有其它方式。
一种是
import turtle as t
这是较常用的一种方式。使用t代表turtle作为前导,可以方便一些。
如t.hideturtle()
另一种
from turtle import *
这表示引用turtle库函数时,不再需要使用前导。虽然会很方便,但若以后引用大量库时,可能会有函数重名,因此,不推荐总使用这种方式。
也可以只导入要使用的函数
from turtle import circle()
这之后便可以使用turtle.circle()
函数
无论如何调用,调用之后,我们既可以使用turtle库来画图。
在画图时,会有一个图标进行移动,这就是我们的画笔。所到之处便会留下痕迹,喻为海龟,故库名turtle。在初始状态下,turtle出现在坐标原点,即画布中心,朝向水平轴正方向。
常用函数
窗体函数
绘制的图形会出现在一个新的窗口,称为画布,如图:
设置显示窗口的大小和位置的函数:
turtle.setup(width,height,starx,stary)
width:窗口宽度.若值是整数,则表示像素;若值是小数则表示窗口高度与屏幕的比例。
height:窗口高度.若值是整数,则表示像素;若值是小数则表示窗口高度与屏幕的比例。
startx:窗口左边沿与屏幕左边沿的距离。若值是None,则表示窗口在水平中心。
starty:窗口上边沿与屏幕上边沿的距离。若值是None,则表示窗口在垂直中心。
画笔状态函数
函数 | 描述 |
---|---|
shape() | 设置图形形状 |
showturtle() | 显示图形 |
hideturtle() | 隐藏图形 |
penup() | 提起笔 |
pendown() | 放下笔 |
pensize() | 设置笔尺寸 |
pencolor() | 设置笔颜色 |
begin_fill() | 填充开始 |
end_fill() | 填充结束 |
fill_color() | 设置填充颜色 |
color() | 设置笔的颜色和填充颜色 |
函数中描述的笔其实就是我们所说的海龟,虽然图中它是一个箭头,但实际上我们可以更改这个形状,其中就包括海龟形状。
turtle.shape()
函数就是用来更改图形的。
可供选择的形状有’arrow’, ‘turtle’, ‘circle’, ‘square’, ‘triangle’, ‘classic’
如turtle.shape('turtle'’)
就可以将形状改为海龟。
而turtle.showturtle()
和turtle.hideturtle()
分别是显示形状和隐藏形状。显示图形的好处是绘制时,界面显得生动活泼,而隐藏图形则可以在一定程度上提升绘制速度。孰优孰劣,仁者见仁智者见智。
有些函数时常作为一组相互配合起作用。如penup()与pendown()
这两个函数分别是提起笔和放下笔。在提起笔状态下,笔移动时,不会在画布上留下任何图形。相反,在放下笔状态,移动笔就可以绘图。他们可以简写为up(),down()
turtle.pensize()
与turtle.pencolor()
分别是设置笔粗细与颜色。设置颜色时,输入指定颜色的名字即可,如turtle.pencolor('red')
即可以将笔颜色改为红色。
turtle.begin_fill()
与turtle.end_fill()
是用来进行填充颜色的。运行在这两个函数之间绘制的图形就会被填充。而填充的颜色可以由turtle.fillcolor()
来设置。类似笔色的设置方法。
另外,可以使用turtle.color('red','blue')
同时设置笔色和填充色.如例,设置了笔色为红,填充色为蓝。
画笔运动函数
函数 | 描述 |
---|---|
speed() | 设置运动速度 |
forward(s) | 向前移动指定距离 |
backward(s) | 向后移动指定距离 |
goto(x,y) | 移动到指定坐标 |
right(a) | 向右转指定角度 |
left(a) | 向左转指定角度 |
setheading(x) | 设置绝对朝向 |
circle® | 画一个圆,参数为半径 |
dot® | 画一个实心点 |
函数turtle.speed()
可以设置画笔移动速度,参数是0-10的整数。0表示最快,1-10逐渐加快,1最慢。
forward(s)|向前移动指定距离
backward(s)|向后移动指定距离
goto(x,y)|移动到指定坐标
right(a)|向右转指定角度
left(a)|向左转指定角度
这五个函数的作用不必多说,是最基本的绘图方式,画一条直线,移动到指定坐标和转过一定角度。
这得一提的是goto()
时常与penup(),pendown()
一起使用,让海归在不绘制图形时移动到指定点。用于另起一处作图。
forward(s)和backfard()
依次可以简写为fd(),bk();
right()和left()
依次可以简写为rt(),lt();
而setheading(x)
所设置的方向,是以x轴为零度,逆时针方向为正的一个角度。如y轴朝向就是setheading(90)
.该函数可以简写为seth()
circle(r)
函数是以当前位置为起点,开始向前画弧线,最后回到出发点,这个弧线就是一个圆。也就是说,乌龟所在位置并非圆心,而是和圆心相距为r的圆弧上的点。
当r为正数,圆心在起始方向的左边;否则在右边。
这个函数还有两个可选参数,分别是steps和extent。steps设置所绘图形是正N边形,不输入是,默认为画圆。当这个参数非常大时,实际上也是画圆,因为圆就是一个正无穷多边形。而extent参数控制海龟完成绘图时转过的角度,默认为360,即整圆。这样即可画一个封闭图形。
dot(r,'black')
函数可以绘制一个实心的点,和设置填充颜色。r为这个点的直径,而不是半径。与circle()
不同,这个点的圆心,就是海龟所在位置。
第二个有趣的实验
看起来海龟库的函数好像十分有趣,我们来尝试一下吧。
由于我们只需装载海龟库一个库,所以我们可以用省略前导的导入方法。
先来试一试画个正方形吧。
想一想,我们用手画正方形时,都是如何完成的呢?
首先,我们需要先画一条线,然后转过一个直角,再画一条线,再转过一个直角,再画一条线,再转过一个直角,再画一条线,再转过一个直角,再画一条线。这样就完成了。
from turtle import *
side=100
fd(side)
right(90)
fd(side)
right(90)
fd(side)
right(90)
fd(side)
right(90)
细心的你可能已经发现,这是一个重复劳动,可以用循环来减少代码量。没错。你可以修改成下面这样:
from turtle import *
side=100
for i in range(4):
fd(side)
right(90)
结果如图
确实节省了很多力气。
确实很有趣。接下来我们再尝试一下画一个五角星。
平时我们画五角星时,都是从一个点出发,画一条线,再转过某一个角度,画一条线,最终画了五条线,画最后一条线时,连到第一条线的出发点就好。那么这个角度就是关键。但通过数学分析,不难得出这个角度。
于是,我们可以通过以下代码绘制一个五角星。同时,我们还可以为这个五角星上颜色。
from turtle import *
pensize(5)
color('gold','red')
begin_fill()
for i in range(5):
fd(100)
rt(144)
end_fill()
结果如图
对了,既然我们可以画一个图形,为什么不多画几个呢?不如画一个奥运五环吧
画一个五环时,唯一的难度在于,我们需要确定每次画圆的开始位置,和半径的大小。合适的位置和半径可以使五个圆相交的样子更具美感。
import turtle
d=40
r=30
turtle.pensize(10)
turtle.speed(0)
turtle.goto(0,0)
turtle.color('blue')
turtle.circle(r)
turtle.penup()
turtle.goto(d,0)
turtle.down()
turtle.color('black')
turtle.circle(r)
turtle.penup()
turtle.goto(2*d,0)
turtle.down()
turtle.color('red')
turtle.circle(r)
turtle.penup()
turtle.goto(d/2,-3**0.5/2*d)
turtle.down()
turtle.color('green')
turtle.circle(r)
turtle.penup()
turtle.goto(d*3/2,-3**0.5/2*d)
turtle.down()
turtle.color('yellow')
turtle.circle(r)
turtle.color('black')
turtle.penup()
turtle.goto(-0.5*d,-2*d)
turtle.pendown()
结果如图
实验过后,我们继续学习接下来的内容。
函数
在进入正题之前,我们先来看一个生活中的例子。
通常我们说做一盘,人们就会明白这不是一个单一的动作,而是一些列行为的组合。比如说西红柿炒鸡蛋吧。它应该包括洗西红柿,打鸡蛋,搅鸡蛋,烧油,炒鸡蛋,加盐,炒西红柿,出锅。其中有些步骤十分关键,不可或缺,比如炒鸡蛋,炒西红柿,而有些步骤因人而异,顺序也可能不同,比如有的人不放盐,有的人可能要加醋,有时炒菜之中忘了,出锅才想起来放。但总体来说,成品是大同小异的,实现近似相同的一个功能,也就是做了一盘西红柿炒鸡蛋。
这就像一个函数,他用一个简单的词句代表了一系列过程。
函数的定义
函数是一段具有特定功能的,可重复使用的语句组,通过函数名来调用。经过定义,一组语句就等价于一个函数。以后即可通过函数名调用这一组被封装的语句来实现它的功能。
函数名就像变量名一样,有相同的规则。python中,通过保留字def定义一个函数。
def <函数名>(<参数列表>):
<函数体>
return <返回值列表>
return部分可以没有,这时这个函数表示执行一个功能。
例如,我们可以将之前使用过的代码封装成一个函数。
>>> def print_triangle():
for i in range(5):
print('*'*i)
>>> print_triangle()
*
**
***
****
在定义函数时,需要注意一个细节,那就是缩进。函数体本身较函数名而言就有一层缩进。
函数定义以后,它并不会自动执行,需要用它的名字调用它,来实现它的功能。
上面我们用的函数,没有定义参数,也没有定义返回值,功能相对简单。
下面尝试我们定义一个相对复杂的函数,它需要一个传入参数。比如,定义一个求整数阶乘的函数。
>>> def fact(x):
result=1
for i in range(2,x+1):
result*=i
print(x,'的阶乘是',result)
>>> fact(6)
6 的阶乘是 720
>>> 6*5*4*3*2
720
定义参数时,像定义变量一样,不需要指定类型,仅需要指定名称。如果有多个参数,则按照你定下的顺序填入即可。
尝试一下,定义一个有三个参数传入的函数。
比如,求前两个数和,再求这个和的n次幂
>>> def binomial_expression(a,b,n):
sum_ab=a+b
result=sum_ab**n
print('%d+%d的和的%d次方的结果是%d'%(a,b,n,result))
>>> binomial_expression(5,3,4)
5+3的和的4次方的结果是4096
在前面所介绍的函数定义,还缺一项常用的东西,那就是返回值。
如果定义了返回值,那么我们可以将运行结果保存起来,方便日后使用。
先给前面用到的函数加一个返回值作为例子吧。
>>> def fact(x):
result=1
for i in range(2,x+1):
result*=i
return result
>>> result1=fact(5)
>>> result1
120
>>>
用保留字return后面跟变量的形式,将一个变量返回,在调用时,相应地,需要用一个变量接收这个返回值。
返回值可以不止一个。我们把前面的例子稍作修改,即可再次利用。
>>> def binomial_expression(a,b,n):
sum_ab=a+b
result=sum_ab**n
return sum_ab,result
>>> sum1,result2=binomial_expression(5,3,4)
>>> sum1
8
>>> result2
4096
现在,我们就可以轻松定义一个有多参数,多返回值的函数了。
函数的参数
函数的参数也是有学问的。
首先我们来看一个例子
>>> a=3
>>> b=4
>>> def fun(a,b):
a*=b
result=a
print('a:',a)
return a
>>> c=fun(a,b)
a: 12
>>> result
Traceback (most recent call last):
File "<pyshell#417>", line 1, in <module>
result
NameError: name 'result' is not defined
在这个例子中,我们把变量a,b传递给函数fun(a,b),在函数内部,执行a*=b,显示a,发现a的值是12.。然后我们在函数运行之后,再查看a的值,发现a的值没有改变。而查看变量result的值时,提示变量不存在。
这就是有关参数的不得不说的问题。
在函数开始执行时,会生成一片空间,专门用来运行函数。在函数中出现的所有变量,都在这个新空间中,与原空间无关。这些参数,被称作形式参数,与原变量只在数值上相同。在函数运行完成后,新空间会被回收。因此,我们再次查看result时,会报错,无此变量。
如此操作的好处是显而易见。我们不必担心函数内部对原变量产生影响。
但如果我们确实需要在函数内部对原变量进行更改呢?
我们可以用保留字global声明全局变量,这样,被声明的全局变量,在函数中被更改时,其本身就会被修改。相当于把这个变量本体送进了函数中。
>>> a=3
>>> b=4
>>> c=0
>>> def f(a,b):
global c
c=a+b
>>> f(a,b)
>>> c
7