在写之前说一些题外话,首先,博主是个新人,刚开始学习不久,有不对的地方欢迎大家指正。其次,这是我写的第一个博客,有经验不足的地方大家见谅。当然,如果可以的话也可以给我一些建议哦,谢过大家!最后,这篇博客主要是写来给自己学习的,刚刚学了一些python的基础感觉还有很多不懂,把一些知识记录下来方便以后复习,所以呢,这篇博客最适合刚开始学习python的朋友啦。好啦,废话就说到这里,下面开始主要内容!
目录
一、程序的运行
- 要运行程序首先要下载一个python的软件,推荐大家去下载pycharm,博主是用这个的,其它的软件还没怎么了解过,有自己喜欢的最好。要下载的后自行去百度一下就可以,是可以免费下载的,博主就不在这提供链接了。
- 和其他的编程语言一样,python也不支持用中文语言进行编程,所以在写代码的时候注意不要输入中文的标点符号哦。当然,中文的标点符号还是可以用的,但必须要用引号包起来。
- python最基础的就是print()函数,print()函数就是python的打印语句,可以将括号中的数字、字符、中文打印出来。
- 另外,python的注释符和C语言、C++的不一样:C、C++是://,python是:# 。
- 详细介绍下print()函数,要打印数字的话,直接将要打印的数字写在括号中就行了。而要打印字符(如英文字母,中、英文符号)和中文的话(数字也可以的,不过这里的数字会被看成数字符了),就要加引号了(只能是英文的引号!!)。python的引号有三种,单引号、双引号和三引号,单引号、双引号只能打印一行的字符(单引号和双引号的作用是一样的),而三引号就可以打印多行的字符了(还有就是,在使用引号时一定要对称的使用,不能一边是单引号一边是双引号,会报错)。给张图举个例子:
6. 另外,print()也可以算是一个计算器,在输入数字时可以如此:
7. 补充一下引号的应用:当要输出的字符串是一句英文句子而且有引号(如:For it's true you are my destiny.),这是就应该用双引号来包住句子,否则会报错。
8. 在6中提到的情况也可以用转义字符来实现输出,如这样:print('For it\'s true you are my destiny.')这样就不会影响用单引号的输出了,同样,双引号。
9. 接下来看一下常用的转义符(看图就行啦):
二、python的数据类型
- python的变量也是有类型,但在定义一个变量时,不需要像C语言或是C++那样同时要给变量分好类型,在python中你只要直接给命名好的变量赋值(数字或者是字符),它就会自动判断你定义的变量的类型,这确实方便很多,比如说:word='language'(被识别成字符串变量),number=123(被识别成整型变量)注:number='123' 也会被识别成字符串。
- python变量的命名规范基本上和C语言或是C++差不多,不过还是复习以下吧:变量不能以数字开头,变量只能由英文字母(a-z或A-Z)、数字和下划线组成,这意味着变量不能有一些特殊符号(如:@、#、¥等,也不能有空格,需要有隔开的地方就要使用下划线啦),最好具有一些可读性,建议尽量用英文来命名(还可以顺便记一下单词)。
- 在此之前,先介绍一下python的print()函数,也就是python的打印语句。它的作用就是将括号内的变量或是字符串或是数字等打印出来。不理解的看下面的图就可以了。
- 字符串可以进行加法的哟,直接用图说明吧(用中文进行加法也是可以的哦):
注:数字类型的变量不能与字符串直接相加,需要进行相加的话需要进行类型转换。
-
python有六种基本的数据类型 :number(数字)、string(字符串)、tuple(元组)、list(列表)、set(集合)、dictionary(字典)。在这里主要介绍下number和string,number(数字)类型又分为四种:int(整型,long(长整型))、bool(布尔型)、float(浮点型)、complex(复数类型);string(字符串)就没那么多分类了,注意下引号就行。
-
和C语言、C++类似,python也可以进行数据类 型的转换:int():将括号中的其他数据类型转为整型,str():将括号中的其他数据类型转为字符串,float():将括号中的其他数据类型转为浮点型。 进行类型转换时需要注意变量是否可以转换(如:int('123')可以,int('abc')就不行) 想了解更多数据类型的知识可以点这个链接:https://blog.****.net/weixin_43444687/article/details/107403433?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_baidulandingword-0&spm=1001.2101.3001.4242
-
最后介绍一下关于数据类型的函数:type()函数,作用是:查询数据类型,如(看图理解):
三、python的条件分支与input()输入函数
- 先介绍一下python的输入函数:input()函数,input()函数运用的格式为:answer=input() ,一定要给它一个变量进行赋值,要是这样的话:input() 就相当于没输入(因为你不给它一个变量名,你也用不了这一个输入,报错倒不会),当然,如果你想对输入进行详细的描述的话,也是可以的,比如:answer=input('请输入你的答案:'),这样就可以了。对于input()函数来说,不管用户输入的是什么,不论是整数 33、小数 3.14 还是火星文,Python 都会统一把它们转换为字符串。所以你还是想输入数字进行数字的运算时,要记得先进行类型的转换,否则会报错。
- 然后就是python的条件分支,还是很简单的,就是格式一定不能错。和C语言、C++基本一样,但还是有不同的(单纯的写字可能描述不清楚,尽量看图吧):
运行结果就不用看了,主要看格式:if (条件):(注:if后面或是else后面的冒号一定不能少!!!)然后就是换行,在条件语句内的语句一定都要缩进!!!不然python不会执行没缩进的语句、或是报错。另外,if的判断条件可以用括号包起来,也可以不用,但是要注意用空格将前面的语句隔开。
- 另外,在if else 语句中也可以进行多层嵌套(与C、C++一样),需要注意的是,每套一层就要多缩进一次,否则程序运行结果不对。
-
然后仔细的介绍一下python的比较运算符(和C、C++基本相同):
这些只要记住就好,没什么特别要求。
-
介绍一下布尔类型:布尔类型的值只有两个,0或1,false或true,即:假和真(0为假,1为真)。在条件语句中,布尔类型是比较常用的。如:if data:。。。else:。。。这样的语句,这是什么意思呢,意思就是:如果data为真,则执行if后面的语句,否则执行else后面的语句。还有一点需要注意的是布尔类型的转换:bool()可以将括号中的语句转换为布尔类型,而布尔类型只有真或假两种值,拿张图举例:
由图可知,只要括号中的变量为 0 或表示什么都没有,那转换为布尔类型后就就为假(或者说 false),只要括号中的变量不表示空和0,那转换后就为true(哪怕括号中的是空格也不算空!)。
- 和其他语言一样,python的条件语句也可以有多路分支,用来进行第二次或是更多次的条件判断的语句是elif语句(相当于else if语句的缩写,当然写成else if会报错)。比较简单,就不拿图举例了。
- 接下来介绍python中的逻辑语句和逻辑运算。python的逻辑运算有三种:或(or)、与(and)、非(not)。
有编程基础的应该很容易理解,知识换了个符号表示而已。举个例子:
and 是两个条件同时成立就为真,or 是两个条件中有一个或是都成立就为真。not常常与成员运算符结合使用:not in 表示。。不在。。。中,成员运算符下一点介绍。当然,not不是只能与in使用,也可以与其他语句一起结合使用,比如:if 。。not true:。。 这样的语句,更多的小伙伴们自己去探索吧!
-
python的条件语句中常用的运算符还有成员运算符---in,顾名思义,in的作用就是判断一个变量或字符串是否属于另一个字符串。说起来不容易明白,用图举例:
这样看就一目了然了。上面的代码中也不用命名变量直接进行字符串的判断。
-
最后就是python中条件语句的三元表达式了:(就拿数的绝对值来举例)
条件语句的三元表达式的作用就是使代码更加简洁。当然,如果不喜欢用也可以不用。
四、python的函数
- 函数的定义:函数是一段组织好的、可重复使用的、用来实现特定功能的代码块。有一些编程基础的基本都知道函数的作用:解决多次出现的同样的问题,尽量避免多次写重复的代码。
- 没有编程基础的也不要着急,让博主慢慢道来。之前提到的type()函数、print()函数就是一种函数,另外,用来转换数据类型的int()、str()语句其实也是一种函数。这些都是python的内置函数,也就是可以直接使用。
- 这一部分我们要学习的就是自己写出有特定功能的函数,也叫自定义函数。要写一段函数,格式与条件语句相同,要进行左对齐。函数的开头就是def name(): ,name是函数名,name后的括号是函数的参数(形参),可以有多个,也可以只有一个,也可以一个都没有(就看你是想写什么样的函数了)。先讲一下参数的类型,参数分为形参和实参,简单地说,形参是不具体的(就像是数学中的一元函数中的变量x),实参是具体的一个数。接下来上图:
其实图中说的一定要有return语句并不全对,我们也可以写一些直接进行打印的自定义函数,那样可能会更加简便。另外,如果图中的return语句没有缩进的话,函数没有返回值,进行print(f(3))的话会打印出报错,接下来上图:
解释一下图中的情况:因为函数中没有retrun语句,函数f(x)没有返回值,但是,我们直接对接果进行了打印,所以python执行了f(3)后,值接打印除了结果10,但是没有返回值,f(3)的值是空的,所以程序打印出了None。
-
接下来对函数进行深入的介绍,之前说到的无参数和多参数:
最常用的print()内置函数就是一个多参数函数。用图举一个例子:
哈哈哈,抱歉打错字了哈,懒得改了,明白就好。也可以在定义函数时就对函数中的参数进行赋值,如:def introduction(name,height,weight,age=18): 。
-
另外,函数也可以有多个返回值,在使用return语句时,返回多个参数值,打印的时候对函数进行赋值就好了,比较简单,博主就不举例了。
区分下return语句的输出与print()函数的输出:
-
函数还有一个重要的点时:变量作用域。简单的说,函数内命名的变量只能在函数中使用,函数外命名的变量既可以在函数外使用,也可以在函数内使用。在函数内命名的变量叫局部变量,在函数外命名的变量叫全局变量。在函数中明明变量时也可以将变量直接变为全局变量,这就用到一个语句了:global语句,格式:global name='小新' 。
-
函数的作用是十分大的,作用范围也非常广,可以和条件语句、循环语句、列表、字典、模块等结合。
五、列表和元组
- 列表的特点:1)可以容纳任意数目不同类型的元素(支持我们学过的任意数据类型)。2)元素之间有先后顺序。3)列表中的元素是可以变更的。
- 给图举个例子,先了解列表的写法:
图中的几个用 [] 包起来的就是列表了。(好像英文中mother打错了,不要笑话我哈。。。。)
-
定义列表时,需要用英文输入法下的 中括号
[]
把里面的所有数据框起来,列表里面的每一个数据叫作元素。每个元素之间都要用英文逗号 (,
) 隔开。 -
列表的元素查找:列表内元素有先后顺序。在现实中我们用“第一个”“第二个”……这种叫法来表示。在 Python 的列表中,也有专门的数字来记录列表内每个元素的位置,称为 索引。和我们数数不同的是,数数是从1开始的,而python的列表索引是从0开是数的,也就是说,列表中的第一个元素对应的索引数字我为0,以此类推。(这其实和C语言的数组一样的)编程语言的列表索引一般都是从
0
开始的,只是在不同语言里 列表 有时也叫做 数组,索引 有时也叫做下标。 python中还有反向索引:列表中的最后一个元素对应的数字是 -1 ,倒数第二个元素对应的数字是 -2,以此类推。拿图举例:这样就很清晰了。
-
当列表中元素中个数较多或是不在明确元素个数时,反向索引就很有用了。不要死脑筋只用一种索引,灵活运用可以更好的运用列表元素。
-
python的列表提供了index()方法,使用 列表.index(元素名称) 的形式,我们可以很方便地获得元素在列表中的索引值:
要是想直接打印出元素的次序记得加1。
-
列表元素是可以修改的:通过直接对列表元素赋上新的值来修改列表的元素。
当然,也可以通过用反向索引来对列表元素进行修改。
-
因为列表中的操作比较多,接下来博主就不一一进行举例说明了,简单的介绍下作用、格式就好,要操作的话就请小伙伴们动动勤劳的小手啦!
-
列表元素的添加(两种方法): 列表名.appened(元素) :在列表末尾添加括号中的元素。 列表名.insert(a,元素) :在列表中添加插入索引为a的元素,原来的列表中索引为a和a之后的元素都往后移。
-
列表元素的删除(三种方法): 列表名.pop(索引) : 返回列表指定位置的元素,并删除这个元素。pop()可以传入一个参数,表示要删除的元素的索引,如果不传入,就默认为最后一个元素的索引。 或者:用 del 列表名[索引] 的方法将索引对应的元素删除。 或者 :用 列表名.remove(元素) 的方法将列表中对应的元素删除。
-
列表的分片:列表分片用一对以冒号分隔的索引位置表示,格式为
列表[起始索引:结束索引]
。比如要获取students
中第三到第五个元素,也就是索引为2
,3
,4
的元素,就要写成students[2:5](后面的索引要加1)
。当然,列表的分片也支持反向索引,比如输出倒数后四位元素:列表[-4:0] 或 列表[-4:] (当索引的起始为第一个元素或结束索引是最后一个元素时,索引可以省略不写,只写开头或结束的索引即可) -
统计一个列表中元素出现的次数: count()方法,格式:列表.count(列表元素)。
-
列表的排序:sort()方法, 格式:列表.sort() 括号中什么都不用填 。 列表的排列有几种,对字符串进行排列:字符串列表的排序按照每个元素首字母的顺序来排序,比如 j 在 l 前面,l 在 x 前面,可以简单地按照 26 个字母顺序表即可; 对数字进行排列:数值列表的排序是按照数值大小从小到大进行排序,比如 1 比 2 小,所以 1 在 2 前面。(其实还有汉字字符串的排列,这个博主没学,想知道的小伙伴自行去百度哈)
-
列表的反转:reverse()方法, 格式:列表.reverse() 括号中不需填元素,空着就好。 主要是需要进行倒序输出时使用。
-
列表的复制: copy()方法 ,格式: 列表1=[] , []中填写一些元素, 列表2=列表1.copy() ,这样列表2中的元素就和列表1中的元素相同了,主要是在需要保留原列表(使其元素的个数、排序等不变)的情况下使用。 这里需要说明一下:直接用 列表2=列表1 这样的方法并不是列表的复制,在python中,这样的操作被看成 : 列表1和列表2只是同一个列表的不同代号,实际是一样的,无论对列表2还是对列表2进行操作,两个列表中的元素都会相同、都会改变。 这就不符合我们要保留原列表的初衷了。
-
列表的清空: clear()方法, 格式: 列表.clear() 括号中为空,这样,这个列表就变成空列表了。 和列表的复制一样,列表的清空和直接将列表命名为空列表时不一样的 :列表=[] ,这样并不是将原来的列表清空,而是将原来的列表名称冠到一个新建的空列表上,而原来的列表失去了自己的代号。
-
列表的操作比较多,这里进行一下概括:(以列表 words=['apple','banana','pear','friend','father','mather'] 进行举例)
列表的添加:words.append('boy') 列表的插入:words.insert(0,'girl') 列表的索引:words.index(banana')
列表元素的移除:words.pop(1) = words.remove('banana') = def words[]
列表中某元素的计数:words.count('banana') 列表的排序:words.sort() 列表的反转:words.reverse()
列表的复制: words.copy() 列表的清空: words.clear()
-
接下来要介绍比较高级的列表操作,不过还是比较简单易懂的。除非必要,博主不会举例,小伙伴们就要勤动动手啦。
-
成员运算符: in ,在之前介绍python的条件语句的时候用它来判断指定字符串是否包含某些字符,现在我们用来判断一个元素是否在一个列表中,格式为:元素 in 列表。这是一个布尔表达式,如果元素在列表中,结果为布尔值ture,反之为false。 成员运算符在这里还是在条件语句中使用的,只是对象变为列表了,还是很好理解的。
-
列表的加法:列表也是可以进行加法的哦,列表的加法也很简单,就是用
+
号将两个列表的元素放在一起组成一个新列表,注意是首尾相连,没有数学中的并集同元素不能重复的说法。还要注意用加法生成的列表的元素顺序,在+
号前的列表元素排在新列表的前面,在+
后的列表元素在新列表的后面。 -
列表的乘法:用 列表*n ,我们可以生成一个元素数目为原列表 n 倍的新列表,列表的乘法也好理解,就相当于两个相同的列表不断相加,注意首尾相连即可。
-
这里介绍一个新的知识:元组!元组和列表非常相似。不同之处在于,外观上:列表是被方括号包裹起来的,而元组是被 圆括号 包裹起来的。本质上:列表里的元素可修改,元组里的元素是 不可以“增删改” 的。还有一个微妙的地方要注意,就是只有一个元素的元组,在格式上与列表是不同的。仅一个元素 x 的列表写成[x], 但仅一个元素的元组要在括号内多写个逗号:(x,)。这是因为 Python 中,圆括号承担的语法功能太多了,可以用来表示元组,也可以用于当数学运算中的小括号(x)这样的写法。(可以用type()函数打印一下单个元素时的元组,看看有逗号和无逗号的区别)
-
元组的数据结构是比较稳固的,不用担心不小心把数据改了。前面介绍的会改变列表中的数据的操作方法不能对元组使用,否则会报错。当然,有几个不会改变元组数据的操作是可以用的。来总结一下可以对元组进行操作的方法:分片、计数、索引、加法和乘法。
-
接下来介绍一个新的函数:zip()函数! 它的作用是将两个长度相同的列表合并起来,相同位置的元素会被一一组对,变成一个元组。结果返回一个组合好的打包对象,需要我们再用 list()函数转换回列表。常常用在成绩排名上,用来将人名和分数联系在一起。
如图所示,要是没有用list()函数将进行组合后的元组变为列表是打印不出来想要的结果的。当然,不是说元组不能打印,如果不是用zip()函数连起来的元组,是可以直接打印的。
-
enumerate()函数:“enumerate”单词本身意思是“枚举、数数”。所以对应的函数功能,就是一个一个地将列表中的元素数出来。enumerate() 函数返回值是 enumerate 类型,也需要用 list() 函数转换。但是要注意:机器还是会从
0
开始数……所以要想从1开始数的话,需要这样:rank=list(enumerate(list_rank,1)), 其中list_rank是举例的一个人名列表。这样就可以,从1开始数了。 -
列表这一部分到这里就结束了,不过光是看看这些知识点或许作用不大,也可能有点无法理解博主说的意思,所以建议每一个知识点小伙伴们都要自己去试过一遍(已经学过的就不用啦)。
六、python的循环
- 接下来试python的循环,对学过C语言或是C++的小伙伴们来说试很简单的啦。循环就是在满足某个条件下不断进行的操作,可以很大程度的减少重复代码(和函数的作用类似)。
- 先来介绍while循环,while循环的语义是当满足某条件时,就一直重复执行某段代码。如图:
循环条件是个布尔值,每次循环都会进行判断,当满足循环条件(值为 True)时执行循环体内的代码,否则结束循环。和之前的条件语句、函数等类似,while循环也要注意缩进,这里就不再细说了。
-
接下来是for循环,python的for循环和C语言就有一定的区别了,注意分清:
我们可以总结出for循环的特性——依次遍历序列中的元素,并依次赋值给变量,最后执行统一的处理。遍历在计算机中指沿着某条路线,依次对序列中每个元素均做一次且仅做一次访问。
-
关于for循环中的序列,序列可以是字符串、列表、元组,但不能是整数。介绍一个快速生成序列的函数:range()函数:
range()函数经常和for循环一起使用,range()函数能方便快速地生成一个序列,有了它我们就能很方便地用 for i in range(n) 写出循环 n 次的代码。 注:range(n)代表从0到n-1的序列。
-
了解一下两种循环的区别:while循环是不知道循环次数的(在一些简单的while循环中可以数出来),而for循环是可以直接知道循环次数的(不用数),for循环中序列中元素的个数其实就是for循环的循环次数。
-
while循环和for循环都可以嵌套多层循环,也可以将while循环和for循环嵌套使用。
-
介绍一下列表生成式:列表生成式 是 Python 中用来快速生成想要的列表的一种简便方式。同样的功能,使用列表生成式只需要一行代码:
下面这个是列表生成式:
-
while循环和for循环都会有死循环,死循环就是因为判断循环继续的变量出问题了,比如 i=0 while i<3: 在while循环的执行语句中没有对i进行操作,那么i的值一直是0,循环条件一直成立,循环就会陷入死循环。都是死循环也是有用的:有时候可以用来没有变量控制、也不知道循环次数的条件下使用死循环,但是要结合break语句和continue语句来使用。
-
介绍两种常用语句:break语句和continue语句,break 和 continue 它俩都只能用于循环内,且都是用于跳过循环:
- 在列表部分提到得zip()函数和enumerate函数也可以使用在for循环的序列中:
好,简单的循环部分就结束了。
七、字符串的操作
- 这一部分仔细讲一下字符串。回顾一下:三引号支持打印多行语句,单引号、双引号不支持。除了使用多行字符串来实现多行文本外,使用 \n 也能达到一样的效果。\n 被称为 换行符,用于文本间的换行。
- 和列表类似,字符串也是可以进行加法和乘法的。看图:
-
字符串类型和数字类型不能直接相加,需要用 str() 函数进行类型转换。
-
字符串格式化输出:
图中%d、%s代表一种占位符,字符串后面的%运算符左边是要格式化的字符串,右边是一个元组。如果只有一个占位符,可以将元组里的元素拿出来。图中的intro就有些类似C语言中使用printf()进行输出的格式。
-
除了用%占位符格式化输出外,也可以用format()方法进行格式化输出:
-
常用的占位符:
如果不太确定应该用什么占位符,%s 是万能的,它会把任何数据类型转换为字符串。
-
字符串有索引和反向索引,分片也和列表相同,不再细讲了。
-
字符串有不可变性,字符串一旦创建后是不可改变的,这个属性和元组类似,通过索引来改变字符串中元素就会报错。要修改字符串的话就要用一个新的字符串:
-
接下来介绍字符串的操作方法:
使用格式都是这样的,比如:字符串.upper() 括号为空。
-
字符串的分割:split() ,用于通过指定分隔符对字符串进行分割。split() 方法有两个可选参数,第一个参数为分隔符,默认为所有的空字符,包括空格、换行(\n)、制表符(\t)等。第二个参数为最大分割次数,默认为 -1,即不限次数。
-
字符串的组合:join()方法,用于将序列中的元素以指定的字符连接生成一个新的字符串。join() 方法接收一个序列(列表、元组、字符串等)作为参数,. 前面的字符串用于连接符。
-
字符串的移除:strip()方法 ,用于移除字符串开头和结尾指定的字符(默认为空字符)或字符序列。当传入一个字符串时,会将传入字符串中每个字符依次移除。
-
概括9、10、11:
-
字符串的计数:和列表一样:count()方法,用于统计字符串中某个字符串出现的次数。第一个参数为要统计次数的字符串,后两个可选参数为在字符串搜索的开始与结束索引。
-
find()方法,用于检测字符串中是否包含子字符串,如果包含子字符串返回第一次出现的索引值,否则返回 -1。第一个参数为要查找的子字符串,后两个可选参数为在字符串搜索的开始与结束索引。
-
字符串的替换:replace()方法,用于将字符串中的指定字符串替换成别的字符串。第一个参数为被替换字符串,第二个参数为替换字符串,第三个可选参数为替换的最多次数,默认为无限次。
-
概括14、15、16:
-
字符串部分就到这里。
八、字典
- 字典 也是 Python 中最常用的数据类型之一。列表 和 字典 都是对象集合。
- 列表是用[]包裹的,元组是用()包裹的。而现在要介绍的字典是用{}包裹的:
图中的字符串'小A'等就是字典的“键”,键后面的数字就是其对应的“值”。需要注意的是,字典中的 键 需要是 唯一的,如果字典中有两个相同的 键,Python 只会保留后面那个。而 值 则没有限制,可以是任意类型的,也可以有相同的值。键和值用冒号(:)连接(英文的哦)。
-
接下来我们来看一下如何进行字典的取值。和列表类似,访问字典中的元素也使用方括号
[]
。不同的是,列表中括号内的是 索引,字典中括号内的是 键。看个例子你就明白了:当然,中括号[]中只能填字典中有的,若是字典中没有会报错。
-
字典的修改、添加和删除,看图:
可以看到,修改和添加都使用 字典名[键] = 值 的方式,如果 键 存在于字典中,就是修改,不存在就是添加。字典元素的删除和列表元素的删除一样也是使用 del 关键字进行删除。删除字典元素时,键 也一定要存在于字典中,否则也会报 KeyError 的错误。
-
字典中常用的方法:
注意:1.keys()、values() 和 items() 方法在 Python3 中返回的是有序序列,必要时需要用 list() 函数转换成列表使用,如 list(scores.keys())。2.gets()是通过 键 获取字典对应的值,当 键 不存在于字典当中时不会报错,而是默认返回 None,也可以通过第二个参数设置不存在时的默认返回值。
-
字典的嵌套:我们之前说过,字典的 键 是 唯一不可变的,而字典的 值 是没有限制的。所以,当字典的值为字典时,就形成了字典的嵌套。在对嵌套字典进行取值时:
-
另外,字典和列表都是 Python 中很常用的数据类型,它们经常被混合着一起使用。比如说:字典的值时一个列表,或是列表的元素是一个字典。
九、模块
- 怎么介绍模块呢?可以将模块也看成一个函数,但是这个函数和我们的mian.py并不在同一个文件里。运用时用的语句也不一样。
- 模块的作用:1.更好的组织代码结构。 2.提高代码复用率。
- 要介绍模块用文字是比较困难的,而且博主也是半桶水。如图(博主用的是pycharm,所以用pycharm举例哈,不过相信其它的软件也是差不多的):
如图,小伙伴们大开pycharm,在左边的栏里找到main.py,右击它,点NEM,然后给它命名:other.py,回车。这样,一个新的模块就建好啦(注意不能随以命名,要加上.py,不然python不会认为这是一个模块)。像这样,每一个单独的 .py 文件,本质上都是一个模块。
-
当我们需要使用模块的时候,只需使用
import
语句导入对应的模块即可。我们来看一个例子,这个例子中有两个模块,一个是 other.py 文件,另一个是 main.py 文件。在导入模块的时候不需要加上模块的后缀。当然,在些写好other.py模块里的代码后,即使将other.py关掉(不是删除),我们菜main.py中也是可以导入并运用other.py模块的。
-
模块的部分导入:
import
语句一次性将整个模块导入进来,我们还可以使用from ... import ...
语句只导入我们需要的变量、函数等。举个例子:可以看到,执行
from other import pi, half
后可以直接使用 other.py 里的 pi 和 half,不再需要在前面加other.
。并且同时导入多个变量或函数时,两两之间要用逗号隔开。 -
简单说一下程序入口:程序入口,指的就是你 直接运行 的那个
.py
文件。举个例子,main.py
中导入了其他的模块other.py
,接着,我们将main.py
直接运行,这时main.py
就是作为程序入口直接运行的,而other.py
则是以导入的形式运行的。 -
接下来介绍python的内置模块。time模块:
time.sleep()这个方法我们在第一课就见到过,它用于暂停程序的执行,参数为秒。它可以用于防止程序执行过快,比如爬取数据时降低爬取速率防止被封等。Unix 时间戳是指格林威治时间 1970 年 01 月 01 日 00 时 00 分 00 秒起至现在的总秒数。Unix 时间戳只是一个单纯不断增长的数字,所以不会存在时区等问题,全球统一,简单便捷。
-
Unix 时间戳对计算机来说稍微计算一下就知道现在是什么时间了,但对人类来说可读性就大打折扣了,所以还有对人类友好的 ctime() 方法:
-
datetime模块:datetime 模块包括很多函数和类,这些函数和类均用于日期和时间的解析、格式化以及计算。
注意,datetime 模块里有一个同名的 datetime 类,因此我们要写成from datetime import datetime。有些时候我们拿到 Unix 时间戳却不知道具体时间,可以使用 datetime.fromtimestamp() 方法来将其转换成人类可读的时间格式。datetime.now() 和 time.ctime() 类似,都是获取人类可读的时间格式,只是 datetime.now() 没有星期几的信息。(看图看图看图!!)
-
有时候我们还要进行日期的计算,这时候要用到datetime模块中的timedelta()方法:
图中调用 timedelta() 时传的是关键字参数 days=5,表示 5 天。其实除了天之外,timedelta() 还支持传入周(weeks)、时(hours)、分(minutes)、秒(seconds)、毫秒(milliseconds)和微秒(microseconds),我们来看看这些参数名都是什么:
还有,timedelta() 可以支持同时传入多个参数,比如计算两个半小时前的时间:
-
time()和datetime()是两个关于时间的内置模块,下面介绍两个关于数字的的模块:random模块:顾名思义,random模块与随机有关:
random.random() 可以生成 0-1 之间的随机小数,包括 0,不包括 1。这是最基本的生成随机数的方法。random.randint(m, n) 可以生成一个随机整数,该整数大于等于 m,小于等于 n。random.uniform(m, n) 也是类似的,只不过生成的是随机小数,该小数大于等于 m,小于等于 n。注意:random.randint() 和 random.uniform() 生成的随机数是包含后面一个数的,这点和 random.random() 还有分片不同。使用random.choice([序列])时,括号中一定要是非空序列,否则会报错。
-
math模块:math模块和C语言中的头文件math是类似的,是关于数字的运算,看图就很明白了:
math模块中的方法和常数当然不止这些,博主懒癌犯了,大家自己去看了:https://docs.python.org/zh-cn/3/library/math.html
-
程序入口:当在做复杂项目的时候,我们会将代码拆分到各个模块中。这样,我们就需要一个程序入口,通过这个入口文件将整个项目的代码串联运行起来。程序入口,指的就是你 直接运行 的那个
.py
文件。举个例子,main.py
中导入了其他的模块other.py
,接着,我们将main.py
直接运行,这时main.py
就是作为程序入口直接运行的,而other.py
则是以导入的形式运行的。 -
程序入口的功能,是指明模块中某一段代码在何时才会被运行。
def bootstrap(): print('项目启动') if __name__ == '__main__': bootstrap()
上面这段代码只有在作为程序入口直接运行时才会自动执行
bootstrap()
,打印出 项目启动。注意:__name__
和'__main__'
前后都是两个下划线。 -
# other.py print('我是 other 模块') if __name__ == '__main__': print('other 模块被直接运行了') # main.py import other print('我是 main 模块') if __name__ == '__main__': print('main 模块被直接运行了')
上面代码的输出:
我是 other 模块 我是 main 模块 main 模块被直接运行了
上面的代码直接运行了
main.py
,第一行代码import other
导入了other.py
模块。other.py
是以导入的方式被运行的,它并不是程序入口,所以,print('other 模块被直接运行了')
这行代码不会执行。屏幕上只会打印出 我是 other 模块。导入other.py
后,接下来就是运行main.py
中的代码啦。main.py
是程序入口,所以print('main 模块被直接运行了')
这句代码会被执行。屏幕上逐行打印出 我是 main 模块 和 main 模块被直接运行了 这两句话。 -
模块的学习就到这了。
十、类与面向对象编程
- 在 Python 的类中,我们把特征和行为分别称为 属性(attribute)和 方法(method)。现实生活中的“类”是我们归纳总结出来的,而 Python 中的类需要我们自行创建。接下来看看如何创建一个类:
-
类的调用:
图中human = Human() 这一行代码非常关键,通过该类创建了一个类的实例对象,这个过程叫做 类的实例化。看看图中human的类型:
<__main__.Human object> 表明这是一个 Human 类的实例对象(object),<class '__main__.Human'> 表明它属于 Human 这个类。
-
self的作用:self 在英文中是“自己、自我”的意思,在 Python 的类中,self 表示创建的实例本身。举例说明:
class Human: arms = 2 legs = 2 hair = '各种颜色的头发' def walk(self): print('直立行走') def speak(self): print('说着各式各样的语言') def intro(self): # 类的方法里访问类的属性 print('人类有%d条胳膊%d条腿' % (arms, legs)) # 类的实例化 human = Human() human.intro() # 报错:NameError: name 'arms' is not defined on line 14
在类的方法里访问类的属性时,发现出现了变量未定义的错误!说明我们在类的方法里直接访问类的属性是不行的。在类的方法内访问类的属性时,类的实例还没被创建。这时,self 就出现了,它的作用是代替实例本身
class Human: arms = 2 legs = 2 hair = '各种颜色的头发' def walk(self): print('直立行走') def speak(self): print('说着各式各样的语言') def intro(self): # 类的方法里访问类的变量 print('人类有%d条胳膊%d条腿' % (self.arms, self.legs)) # 类的实例化 human = Human() human.intro() # 输出:人类有2条胳膊2条腿
当执行 human.intro() 这行代码时,Python 会将 human 作为第一个参数偷偷传递给 self,这样我们就不再需要传入第一个参数,并能通过 self 访问类的属性和方法了。
-
总结一下self的作用:1.在创建类的方法时,必须要将第一个参数留给self,并在调用的时候忽略它(忘了写self会报错) 2.在类的方法中调用类的属性和方法时,要通过self.属性名和self.方法名()的格式调用。
-
总结一下进行类的调用的步骤:1.创建一个类;2.进行类的实例化;3.通过类的实例调用类的属性和方法。
-
在 Python 的类中,有一种特殊的方法——初始化方法。它的格式是
def __init__(self):
,方法名由init
(initialize 的缩写,初始化的意思)加左右两边的 双下划线 组成。初始化方法的特殊之处是:每当进行类的实例化时,初始化方法会自动被执行。举例:class Human: def __init__(self): print('Hi,我是 Human 类的初始化方法') human = Human() # 输出:Hi,我是 Human 类的初始化方法
可以看到,我们只是创建了实例,并没有调用
__init__
方法,它自己就自动执行了。利用这个特性,我们通常会在 初始化方法 里完成类属性初始值的设置。如:class Human: def __init__(self): # self.不能丢 self.arms = 2 self.legs = 2 self.hair = '各种颜色的头发' def walk(self): print('直立行走') def speak(self): print('说着各式各样的语言') human = Human() print(human.hair) # 输出:各种颜色的头发
除了进行固定的初始值设置,初始化方法 可以接收其他参数,进行自定义的属性初始值设置。如:
class Human: def __init__(self, name, arms, legs, hair): # self.不能丢 self.name = name self.arms = arms self.legs = legs self.hair = hair def walk(self): print('直立行走') def speak(self): print('说着各式各样的语言') def intro(self): print('我叫{},我有{}'.format(self.name, self.hair)) cainiao = Human('菜鸟', 2, 2, '黑色的头发') print(cainiao.name) # 输出:菜鸟 cainiao.intro() # 输出:我叫菜鸟,我有黑色的头发
图中初始化方法额外添加了 4 个参数,因此在实例化的时候要传入对应的值。
-
像
__init__
这样的方法在 Python 的类中被称为 神奇方法(或魔术方法),它们的特征是被 双下划线 所包裹。下面介绍另一个神奇方法:__str__()。 -
class Human: arms = 2 legs = 2 hair = '各种颜色的头发' def __str__(self): return '人类有%d条胳膊%d条腿' % (self.arms, self.legs) def walk(self): print('直立行走') def speak(self): print('说着各式各样的语言') human = Human() print(human) # 输出:人类有2条胳膊2条腿
可以看到,有了
__str__()
方法,直接打印实例的结果为__str__()
方法的返回值。因此,我们可以使用__str__()
方法来描述一个类。 -
面向对象与面向过程。面向过程的思维方式:把一个问题拆分成一个个步骤,然后用函数实现各个步骤,依次调用解决问题。 面向对象的思维方式:把一个问题拆分成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描述某个事物在整个解决问题的步骤中的行为和特征(方法和属性)。
使用面向对象的思维方式的好处是:程序的可读性、可拓展性、可维护性高。
-
类的继承:继承 这个词很好理解,比如你继承了家族的千万家产,什么都没干就一夜暴富。类的继承也是如此,子类 继承了 父类,什么都没干就有了父类所有的属性和方法。举个例子:
class Human: arms = 2 legs = 2 hair = '各种颜色的头发' def walk(self): print('直立行走') def speak(self): print('说着各式各样的语言') class Chinese(Human): pass xiaobei = Chinese() print(xiaobei.arms) # 输出:2 xiaobei.walk() # 输出:直立行走
注:pass是空语句,表示跳过,什么都不做。可以看到,Chinese 类中什么都没有,实例化出来的 xiaobei 却拥有 Human 类的属性和方法。通过 class 子类名(父类名) 的方式实现了类的继承,让子类拥有了父类的所有属性和方法。
-
类的继承有多层继承:继承不只是子类继承父类的属性和方法,当父类还有自己的父类时,子类也能继承父类的父类的属性和方法。
class Human: arms = 2 legs = 2 hair = '各种颜色的头发' def walk(self): print('直立行走') def speak(self): print('说着各式各样的语言') class Chinese(Human): pass class JiangSu(Chinese): pass xiaobei = JiangSu() print(xiaobei.arms) # 输出:2 xiaobei.walk() # 输出:直立行走
类的属性和方法会通过继承一直传递下去,减少了大量的重复代码,实现了代码的复用。
-
类的多重继承:除了继承一个类,我们还可以同时继承多个类,语法是 class 类 A(类 B, 类 C, 类 D):。举例:
class Chinese: hair = '黑头发' skin = '黄皮肤' def speak_chinese(self): print('说汉语') class American: hair = '金头发' skin = '白皮肤' def speak_english(self): print('说英语') class ABC(Chinese, American): pass abc = ABC() print(abc.hair) # 输出:黑头发 print(abc.skin) # 输出:黄皮肤 abc.speak_chinese() # 输出:说汉语 abc.speak_english() # 输出:说英语
可以看到,ABC 类继承了 Chinese 类和 American 类的所有属性和方法,但 hair 和 skin 这两个类都有的属性,ABC 类只继承了 Chinese 类的。这是因为 class ABC(Chinese, American): 中 Chinese 靠前,调用实例的属性和方法时会优先在子类中查找,找不到再从最左侧的父类依次往右查找,直到找到为止,如果都没有找到则会报错。
-
总结下两种继承方式:
-
类的定制。可以在父类的基础上做以下两点定制:1.创建新的属性和方法 。 2.修改继承自父类的属性和方法。类的定制的两个特点:新增 和 重写。新增 指在继承父类的属性和方法的基础上添加自己独有的属性或方法。重写 指在继承父类的属性和方法的基础上重写父类的属性和方法。
-
类的知识比较多,总结一下:
需要注意的点:1.定义类的方法时,第一个参数 self 不能丢,调用方法时要忽略;2.self 作用是代替实例本身,在类中访问类的属性和方法;3.初始化方法 __init__() 在类实例化时会自动执行,一般用于类属性的初始化;4.子类可以继承父类的所有属性和方法,并且可以定制自己的属性和方法。
十一、python绘图
- turtle:turtle 是 Python 中自带的绘图模块。turtle单词的中文意思是 海龟 。turtle 的方法有很多,博主就介绍几个简单的(画星星),大家有兴趣可以去官方文档了解更多。官方文档地址:https://docs.python.org/zh-cn/3/library/turtle.html
- 想像一个直角坐标系:我们的海龟的起始位置就在原点。海龟的颜色默认是黑色的,我们可以使用
turtle.color('red')
改成红色的。当然,你也可以使用turtle.color('yellow')
改成黄色,使用turtle.color('pink')
改成粉色等等。海龟的朝向是前方(默认朝东),我们可以调用turtle.forward(3)
让画笔前进 3 像素,也就是海龟移动到了坐标系中 (3, 0) 的位置。因为我们的画笔默认是落下的,因此在移动的过程中会留下一道轨迹,即一条长 3 像素的直线。除了前进之外,当然也有后退。调用turtle.backward(3)
即可让海龟向后倒退 3 像素,移动到坐标系中 (-3, 0) 的位置,同样也会留下一条长 3 像素的直线。注意:后退后小海龟的朝向是不变的。之后我们会学习让小海龟转向,也就是调整小海龟前进的方向。 - 海龟转弯:转弯其实很简单,分为左转和右转。左转是
turtle.left()
,右转是turtle.right()
。它俩的参数是角度,比如turtle.right(90)
表示右转 90 度。同理,turtle.left(90)
表示左转 90 度。import turtle turtle.forward(100) turtle.right(90) turtle.forward(100) turtle.right(90) turtle.forward(100) turtle.right(90) turtle.forward(100) turtle.right(90)
这段代码就可一画出一个宽100像素的正方形。
-
turtle.left()
和turtle.right()
每次转向都是根据当前朝向来转的,当多次转向后你可能就不知道现在朝向哪了。因此,我们还可以使用turtle.setheading()
来直接设置朝向。turtle.setheading()
的参数也是角度。我们可以直接调用turtle.setheading(0)
让小海龟朝东,调用turtle.setheading(180)
让小海龟朝西。当然,0 到 360 度之间的角度都是可以的,调用turtle.setheading(45)
可以让小海龟朝向东北方向。 -
隐藏小海龟可以加快绘图的速度,并且最后画出的图上也不会有个小海龟影响画风。要隐藏小海龟非常的简单,只要调用
turtle.hideturtle()
即可。当你想再次显示小海龟时,调用turtle.showturtle()
即可。 -
我们来画一颗五角星,五角星每个角的度数都是 36 度,用 180 - 36 得到对应的补角为 144 度。下面的代码运行就得到一颗五角星啦:
import turtle turtle.color('red') turtle.hideturtle() for i in range(5): turtle.forward(100) turtle.right(144)
这还不够,我们还要给五角星上色。上色需要设置填充颜色,turtle.color() 会将画笔颜色和填充颜色都设置成一个。而调用 turtle.fillcolor() 能单独设置填充颜色,你也可以调用 turtle.pencolor() 单独设置画笔颜色。
-
设置好填充颜色之后,上色需要调用两个方法,分别是 turtle.begin_fill() 和 turtle.end_fill()。从名字就可以知道,一个是开始填充一个是结束填充。画一个红色五角星的完整代码如下:
import turtle turtle.color('red') turtle.hideturtle() turtle.begin_fill() # 开始填充 for i in range(5): turtle.forward(100) turtle.right(144) turtle.end_fill() # 结束填充
但是上面代码运行出来得五角星并不在正*,因为海龟得起始位置在正*,画出来的当然会是这样。要让五角星出现在正*,就要调整海龟的其实位置:调用 turtle.goto(x, y) 来移动画笔的位置。第一个参数是 x 轴的坐标,第二个参数是 y 轴的坐标。 但直接移动画笔位置是有问题的,因为我们的画笔一直处于落下的状态,移动的过程中也会画出一条直线。我们可以调用 turtle.penup() 将画笔抬起,这样移动的过程中就不会画线。等需要时再调用 turtle.pendown() 将画笔落下开始绘图。边长为 100 像素的五角星移动坐标系*的完整代码如下:
import turtle turtle.color('red') turtle.hideturtle() turtle.penup() turtle.goto(-50, 20) turtle.pendown() turtle.begin_fill() for i in range(5): turtle.forward(100) turtle.right(144) turtle.end_fill()
-
控制绘图速度的方法:turtle.speed(0) ,turtle.speed(0) 的参数是 0-10 的整数,其中 1-10 数字越大,绘图速度越快。1 最慢,10 最快,默认是 6。而 0 表示没有动画效果,因此 0 比 10 的速度还要快。
-
画多个星星。满天星的位置都是随机的,我们需要用到 random 模块生成随机位置。因为教学环境中显示区域有限,随机位置在 x 轴上的范围是 -150 到 150,在 y 轴上的范围是 -100 到 100。随机画 50 颗小星星的代码如下:
import turtle from random import randint def draw_star(): turtle.color('white') turtle.hideturtle() turtle.begin_fill() for i in range(5): turtle.forward(10) turtle.right(144) turtle.end_fill() for i in range(50): turtle.speed(0) # 最快速 turtle.penup() x = randint(-150, 150) # x 轴 y = randint(-100, 100) # y 轴 turtle.goto(x, y) turtle.pendown() draw_star()
满天星画完了,我们最后再署个名。调用 turtle.write() 可以在画板上写字,参数为要写的内容。我们还能设置字的字体、大小等。
呜呜,到这里我的第一篇博客就写完了,花了十几天,虽然不是每天都在写,但也是好累的。这些知识点都是博主在一个python教学网站上学的(当然要花钱),因为打开比较麻烦,不方便复习,所以博主就写了这片博客,当然,如果你没学过python的话,我认为你把这篇博客的内容都弄懂了,python的基础基本就学全了。(博主其实没懂全~~)。
写得好辛苦了,大家点个赞在走吧!