目录
第一章
1.编程是做什么的
2.为什么学python
3.从hello Word开始
第二章
1.python的运算
2.python中的变量
3.python中的条件语法
4.python中的循环语法
第三章
1.python中的函数
2.函数中的参数传递(传参)
3.解包裹
4.递归
5.python中的模块
6.python的异常处理
第一章
1、编程是做什么的
编程可以调用计算机的基本指令而使计算机完成特定的操作,但如完全用基本指令来说明所有的操作,代码将会超乎想象的冗长,怎么办?在程序中,有很多特定的指令组合会重复出现,如果能够将这些特定的指令组合代码封装(packing)起来,即把执行特殊功能的指令打包成一个程序块,然后给这个程序块起个容易查询的名字,在需要重复使用这个程序时就可以简单的通过名字调用。
封装代码的方式有很多种,不同的方式对应着不同的编程范式(Programming Paradigm),根据不同的编程范式又区分出不同的阵营,有面向过程编程的C语言、面向对象编程的Java语言、面向函数编程的Lisp语言等,任何一种编程范式编写出来的程序,最终都会翻译成所需要的简单功能组合。python是一门多范式语言,它提供了一个对比学习多种编程范式的机会,在同一语言框架下,如果程序员能清晰地区分出不同 的编程范式,并了解各自的利弊,将起到事半功倍的效果。
在学习了包括python在内的任何一门编程语言后,就打开了计算机世界的大门。通过编程,你几乎可以发挥出计算机所有的功能,给创造力提供了广阔的施展空间。你可以用它来写程序解决小说中的词频统计、建立一个互助学习的网站等问题,此外你还可以得到经济性和声誉性的回报。时代在改变,机器生产逐渐在取代传统的劳力生产,机器的调配和占有能力正在改变世界的工作格局。很多人意识到程序员的需求量在不断加大而都在自学编程,以便跟上潮流。
2、为什么学python
高级语言的关键是封装,让程序编写变得简单。Python正是因为在这一点上做得优秀,才成为主流编程语言之一。Python的使用相当广泛,是Google的第三大开发语言,也是Dropbox、Quora、Pinterest、豆瓣等网站主要使用的语言。在很多科研领域,如数学、人工智能、生物信息、天体物理等, Python都应用广泛,渐有一统天下的势头。
python经过了二三十年的发展,逐渐形成了自己区别于其它语言的优势。
第一,C语言能偶调用计算机所有的功能接口,但其需要复杂的代码进行编程;shell可以通过简单的几行代码就可以运行C语言上百行的代码的程序,但是shell的本质只是调用命令而不是一个真正的语言;ABC语言具备了良好的可读性与易用性,但其对电脑配置要求比较高且过度的革新加大了程序员的学习难度……而吉多·范·罗苏姆(Guido von Rossum)开发的python编译/解释器则综合了以上各种语言的优点,使得其具备了功能全面、易学易用、可拓展等优势。
第二,python能调用C语言生成的动态链接库,从出生到现在一直保存着基本的语法:类(class)、函数(function)、异常处理(exception)、包括表(list)和词典(dictionary)在内的核心数据类型,以及模块(module)为基础的拓展系统,大大降低了程序员的学习难度。
第三,python的拓展性强,你可以引入其他人编写的python文件来为自己的代码拓展功能,还可以直接引入C和C++语言编译出的库,python就像站在了巨人的肩膀上。
第四,python具有功能丰富的模块,既有自己的标准库,也有标准库之外的第三方库,由于python的开发者来自不同领域,他们将不同领域的优点带给了python,使得程序员可以借助已有的库再加上简短的代码就可以实现python在不同领域中的灵活运用。
3.从Hello World开始
在python上执行命令最简单的方法就是直接在python的命令行中直接输入指令,然后按enter键运行。比如,我想让计算机打印出“Hello Word”,我就可以在命令行中输入print(“Hello Word”)然后敲enter键确认,屏幕上就出现了“Hello Word”。
输入的print()函数表示打印,括号里可以用一对引号引出打印的内容。
使用python的第二种方式是编写一个以".py"结尾的程序文件(Program File)。可以用任何文本编辑器来创建和编写,这里以用Pycharm为例。创建一个以“Hello Word.py"为文件名的Python File,输入print(“Hello Word”),点击保存,然后再选择Run这个文件,同样也可以在屏幕中打印出“Hello Word”。
我们在平时的练习和工作中一般是使用程序文件来编写程序,因为它可以编写大量的程序,且更容易保存和更改,也可以加入注释(注释以#号引出,并不会被当作程序执行)使得代码具有更强的可读性。在进行注释或者打印时,如果内容太多可以用三对引号(""" """)进行引用而使得内容可以分行,如下所示
在这里需要注意的是,如果使用的是python 2 ,在使用到中文编程前需要在程序开始之前加上一行编码信息,以说明程序文件中使用了 支持中文的utf-8编码。在python 3中不需要这一行信息。
第二章
1.python的运算
python可以跟计算器一样进行基础运算,加、减、乘、除、乘方(3的二次方有三种表达:3^2、3**2、pow(3,2))、求余数(10%3,表示10/3的余数,结果为1)。除了常见的数值运算外,字符串也能进行加法运算,效果是把两个字符串练成一个字符串。如输入"Hello"+"Word"会输出 HelloWord 。一个字符串还可以进行乘法运算,结果是把该字符串重复n次,如输入"hello" * 3 会输出 hellohellohello 。
python还可以进行逻辑运算。计算机在二进制体系下,可以用1和0来代表给出命题中的“真”和“假”两种状态,python中使用了True和False两个关键字来表示真假,它们被称作布尔值(Boolean)。在较为复杂的逻辑运算中,我们会用到:and表“与”、or表示“或”、not表示“非”,他们的运算关系为:
除了数值运算、逻辑运算外,还有判断表达式的运算,如“1=1”在python中可以写成“1==1”,返回的结果为True,判断运算符有
单纯的数值运算、逻辑运算和判断表达式都不需要用到计算机,这样会显得小题大做,但是当三者放在一起之后,计算机才真正显示出它的威力。举个例子,房产价格86万元,税率15%,首付20%,假如我手里有40万现金,出于税务原因,我还希望自己付的税款低于13万,那么是否还可以买这套房子?这个问题可以借用python进行计算
数值运算符、逻辑运算符、判断表达式均为运算符号,当一个表达式中出现多个运算符时,也要遵循一定的运算顺序,运算符按照优先级先后进行运算
2.python中的变量
在上面的运算中,所算出来的运算结果并不会自动保存,它们会随着下一步的运算而消失。如果我们想在下面的运算中仍然可以运用之前所算出来的结果,我们可以将每一个需要用到的运算结果赋值给一个变量存储到存储器中,以至于可以让计算机可以记住它们并且可以很方便的提取它们。如,可以将“Vivian”赋值给V,那么在以后的运算中需要用到“Vivian”时就可以直接输入变量V了
当变量被赋值为数字的时候,该变量还可以通过数值运算重新赋值给自身,如
上面的方法通常还可以表示为
这里说的变量的用法,跟我们在数学课本上讲的变量一样,给出函数关系式,当自变量取不同值的时候,输出的因变量也会发生变化,因此我们可以通过变量来研究各种复杂的关系变化。
变量的类型可以细分为整数(int)、浮点数(Float)、字符串(str)、布尔值(bool),我们可以通过函数type()函数来查看变量的类型,如
特殊的变量1:序列。序列是一种容器型变量,它能像容器一样收纳多个数据且是有序的,所收纳的每一个数据被称为“元素”,列表可以包含一个或者多个元素,也可以是没有元素的空序列。序列有分为两种,一种是元素不可以改变的元祖(Tuple),另一种是元素可以变更的列表(List),可以通过Type()函数来查看序列的类型。在python上,可以通过小括号对来创建元祖,通过中括号对来创建列表,如
把各种元素储存在序列以后,当我们想要读取序列种的元素时,就可以通过序列名[元素下标]来读取了。Python中序列的下标从0开始,即第一个元素的对应下标为0。如
由于列表里面的元素可以发生变更,我们可以通过下标来对某个元素进行赋值,或者增加元素:
我们不仅可以在序列中查找单个元素,还可以通过范围引用的方式来找到多个元素。范围引用的基本样式是:序列名[下限:上限:步长],其中默认的步长为1
此外,python除了可以顺数引用外,还提供了一种尾部引用的语法
特殊的变量2:词典。词典很多方面都和列表类似,它同样是一个可以容纳多个元素的容器,但词典不具备序列那样的连续有序性,所以适于储存松散的一组数据。词典的构建形式是:词典名={}。词典不是以位置来作为索引的。词典允许用自定义的方式来建立数据的索引:
3.python的条件语法
最早的程序都是按顺序刻板的运行,如果遇到需要不停重复的工作,那么只好写入足够多的重复的代码好让程序正常运行。为了让程序能更灵活,早期的编程语言加入了“跳转”的功能,使得程序在运行到某一阶段就会跳转到任意一行继续执行,但这种方法需要在程序中间不断加入“跳转”的代码,使得程序既难读又容易出错。后来程序员渐渐发现,跳转的最主要功能,就是选择性地执行或者重复执行某段程序,这就是我们现在所说的“选择”和“循环”。举个例子,如果一个房子的售价超过50万,那么交易费率为1%,否则为2%。我们用选择结构来写一个程序:
这是一段简单的选择的条件语法:如果总价超过50万,那么交易费率为1%;否则,交易费率为2%。if引出的条件如果成立,则会执行if的从属代码(可以不止一行),如果不成立,则会执行else的从属代码,从属代码需要有四个空格的缩进。另一种情况,如果没有else,当if引出的条件不成立时,计算机会不执行任何代码。
如果程序有多个选择,也就是有多个条件,那么我们会用到if……elif(可以多个)……else,结构,其中if和elif的用法一样,后面跟条件语句,如:
4.python的循环语法
上面说到,要实现“跳转”功能,除了要用到“选择”的语法外,还要用到“循环”的语法。循环用于重复执行一些程序块,在Python中,循环有for和while两种,我们先来看for循环。
for循环的一个基本用法是在in后面跟一个序列,表示循环的内容来自列表,列表中元素的个数就是循环的次数,for循环的从属代码就是需要重复循环的内容。
如果只想简单地重复特定次数,那么我们可以使用Python提供的range()函数:
while循环的用法是后面紧跟一个条件,如果条件为真,则会一直执行隶属与它的语句,知道条件为假是循环停止。如
如果while的条件一直为真,那么就产生了无限循环,知道程序被打断或者电脑关机才能停止。无限循环多用于图形程序中,用于检查页面的状态。无限循环最简单的条件是:True。
当无限循环需要终止或者跳过时,可以用break(停止整个循环)、continue(跳过此次循环,进行下一次循环操作),如:
第三章
1.python中的函数
工作中我们常常用到函数去解决问题,在python里定义函数的方法是通过“def functionname(a): ”来给函数命名,括号里面是函数中的参数,可以有多个也可以没有(需保留括号)。定义好函数名称和参数后,下面代码是隶属于该函数的表达式(缩进四个空格)。在定义完函数表达式后,以“return+变量”来终止和返回值给某个或多个变量,此时即使后面还有代码也不会被执行。
定义完函数后,我们在需要时可以调用该函数,方法是:funtion(a),此时的a应该是具体的数值,然后该函数就可以运行并得出返回的值,一般情况下会将返回值赋予给变量保存。
当我们用到一些别人写好的函数时,如果不知道该函数怎么用,我们可以通过help(funtionname)来找到这个函数的说明。如果想给我们自己写的函数添加说明时,可以在定义完函数名称后在下面一行代码中用三引号对引出函数说明(缩进)。
2.函数中的参数传递(传参)
以“def print_arguments(a,b,c):”所定义的函数为例,最简单的传参方式是按参数顺序赋值,即“print_arguments(1,2,3):”那么参数的取值就是a=1,b=2,c=3.如果想要不按顺序赋值,可以用关键字(keyword)的方式传参,即"print_arguments(c=3,b=2,a=1):",产生的结果跟前者一样。有时候不需要给参数传参时,可以在定义函数的时候就给参数赋值(默认值),这样在不需要传参时该参数就使用默认值,需要传参时就给参数赋予新的值。
有时候我们在定义函数的时候并不知道参数的个数,这时就需要用到包裹传参,用法为:
*all_arguments表示定义参数为一个元祖(前面若有两个*则表示定义参数为一个词典),在传参的时候会将参数赋值到元祖相应的位置,这时候调用函数时参数就可以是任意多个了。并且和之前一样,包裹传参也有位置和关键字两种形式。
3.解包裹
前面说到*和**用来定义函数参数为一个元祖或者字典,*和**还有另外一个作用,就是在解包裹的时候调用函数。什么是解包裹,可以理解成:我们将各个参数放在了一个列表序列中,当调用函数传参时想传递序列里面的参数,但是直接引用序列的话python只会将整个序列看成一个参数,从而发生错误。这时候就需要将序列里面的各个参数“释放”出来再完成参数传递,这就是解包裹。
这里就是将arges元祖里面的元素解包为参数传到函数中,传参时要在元祖前面加上*提醒python。
4.递归
递归就是在函数的定义中调用其自身的操作,如
上面是算1到100的和的代码,当中使用了递归的方法。n==1是函数运行的终止条件,表示当函数运行时运算100+99+98+……一直加到n=1时,返回一个常数使得不再重复运行函数,继而得到结果。尽管整个递归过程很复杂,但在编写程序时,我们需要关注初始条件(n=100)、终止条件(n=1)及衔接。
程序中的递归需要用到栈(stack)这一数据结构。所谓数据结构,是计算机存储数据的组织方式。栈是数据结构的一种,可以有序地存储数据,它储存数据的特征是“先进先出”,用弹出(pop)操作取出栈顶元素,用推入(push)操作存入新元素到栈顶,每个元素称为帧(frame)。继续以上面定义的函数为例,我们为了算gaussian_sum(100),要先算gaussian_sum(99),一直算到gaussian_sum(1),这样就产生了很多未完成的函数调用。在每次函数调用时,我们在栈中推入一个新的帧,用来保存这次函数调用的相关信息。栈不断增长,直到计算出gaussian_sum(1)后,我们又会恢复计算gaussian_sum(2)……这样就相当于我们又把帧弹出来了,知道最后栈清空了,程序就完成了。
5.python中的模块
所谓的模块,可以简单理解成:一个.py文件,文件里面装有多个函数。python通过引入(import)模块可以调用里面的函数,方法是:from 模块名 import 函数名。这样,在后面的代码中,就随时可以调用该函数了。我们把常用的功能编入到模块中,方便未来使用,就成为所谓的库(library),库在我们后面的工作中会经常使用到。
当库文件和应用文件放在同一文件夹下时,python会自动在该文件夹下搜索它想要引入的模块。但Python还会到其他的地方寻找库:1.标准库的安装路径。2.操作系统环境变量PYTHONPATH所包含的路径。标准库是Python官方提供的库。Python会自动搜索标准库所在的路径。因此,Python总能正确地引入标准库中的模块,如果是自定义的模块,则可以放在自认为合适的地方,然后修改PYTHONPATH这个环境变量。当PYTHONPATH包含模块所在的路径时,Python便可以找到那个模块。
6.python的异常处理
程序缺陷,也就是程序bug,是我们在运行程序时经常会遇到的问题。当程序报错时通常会以“IndexError:”引出报错内容。程序错误分为两种,一种是运行时错误(Runtime Error),这种错误比较容易发现和修复。另一种是语义错误(Semantic Error),这种错误是程序没有问题可以正常运行,但表达的结果并非是自己想要的,所以这种错误最为隐蔽,也最难纠正。
程序缺陷的修改成为debug,作为初学者,我们可以用print()函数去查看变量的状态以及运行进度,从而发现错误的地方并进行修正。另一种方法就是把debug作为写程序的手段,我们可以先写一个简单的小程序来实现特定的功能,再根据需求不断修改,使程序不断进化以满足最终的复杂需求,这样就相当于在不断的改正程序中的某些错误,这种开发程序的方法叫做测试驱动开发(Test-Driven Development,TDD)。
我们还可以提前写好相应的代码来应对异常的发生,这样做的目的一个是让程序终止前进行更多的操作,比如提供更多的关于错误的信息,另一个目的是让程序犯错后依然能运行下去。如下面代码
上面异常处理完整的语法是
如果try中有异常发生时,将执行异常的归属,执行except。异常层层比较,看是否是exception1、exception2……直到找到其归属,执行相应的except中的语句。如果try中没有异常,那么except部分将跳过,执行try和else中的语句。finally是无论是否有异常,最后都要做的一些事情。此外,如果except后没有任何参数,那么表示所有的异常都交给这段程序处理。
代码见我的马云
zun: happy - Gitee