本文浓缩了Python最基础的概念以及最常用的基本语法,以最简单快速的方法让大家感受这门"解释型编程语言"的风格,文中所涉及的内容会在本系列后面的文章中详细介绍。欢迎来到Python的世界!
Python是一种面向对象、解释型计算机程序设计语言,由Guido van Rossum于1989年发明;
编程语言分为"编译型语言"和"解释型语言"两大类,Python是"解释型语言",运行前会自动将py源码文件编译成字节码文件(pyc,pyo),然后再使用"python解释器"去运行这些字节码文件,"python解释器"负责将字节码文件翻译成机器码执行,而"编译型语言"(JAVA、C、C++等)在编译过程中直接将源代码文件编译成"机器码"文件,所以"编译型语言"在编译后生成的可执行文件实际上是计算机可以直接运行的"机器码",这就是为什么"编译型语言"比"解释型语言"运行速度快的原因。
本系列文章所有实例都是在Linux系统下演示的,我们假设读者在此之前已经搭建好了Python开发环境,大部分实例代码都是使用Python3语法编写,部分语法可能并不兼容Python2。
首先,使用文本编辑器,输入下面的内容:
#!/usr/bin/env python3 #coding=utf-8 print("Hello","World")
将这段内容保存成后缀是.py的文件,比如hello.py(在Windows操作系统中,py后缀是必须的,而在Linux系统中没有扩展名同样能够运行,但作为约定,我们总是使用.py后缀作为Python控制台程序与Python模块的扩展名,用.pyw后缀作为GUI程序的扩展名)。
在python中,所有#后的内容都为注释,但本例中前两行的注释是有实际作用的,在Linux中执行这段代码时,代码的头两个字节首先被读入,如果这两个字节是ASCII字符#!,shell就会认为该文件将要由"解释器"执行,并且该行的后面指定了要使用哪个解释器执行这些代码,该行称为shebang,编写Python程序时,shebang最常见的两种形式如下:
#!/usr/bin/env python3
这种格式,会让shell自动寻找当前环境中能够使用的第一个python3解释器,用来执行文件中的所有代码;
#!/usr/bin/python3
如果要使用指定的解释器,就使用这种方法,这条语句声明,使用/usr/bin目录下的python3解释器来执行这个文件中的所有代码,如果解释器放置在其他目录,可以使用完整路径替换;
默认情况下,python文件使用utf-8字符编码,但在中文环境中开发时,最好在源码文件开头添加"#coding=utf-8"语句(这不是必须的)。
上面的代码中的最后一行,同C语言的printf一样,用来在屏幕上输出"Hello World",不同于C语言的是,Python可以使用逗号隔开每段字符串,每个逗号都会被一个空格替换,并将双引号中的字符串内容连接起来输出。
Linux中使用python3解释器来执行hello.py文件,输出如下:
www@qingsword.com:~$ python3 hello.py Hello World #如果我们给hello.py添加了可执行权限,那么就可以直接使用文件名来执行 www@qingsword.com:~$ sudo chmod +x hello.py www@qingsword.com:~$ ./hello.py Hello World
在Windows环境中,请确认python的安装路径,然后在cmd中用python安装目录下的python.exe来执行hello.py文件:
#假如python3安装在C盘的Python30目录中,hello.py文件放在C盘py3目录下 C:/py3> C:/>Python30/python.exe hello.py Hello World #Windows下能够直接使用文件名来运行py文件,但有时因为系统中同时安装了python2和python3,直接执行时有可能默认调用的是python2的解释器,如果遇到这种情况,可以使用第一种方法,使用python3解释器的完整路径。 C:/py3> hello.py Hello World
除此之外,Python安装包中应该包含IDLE组件(Python shell),这是一个测试Python时非常好用的编辑器,Windows用户安装完成Python后可以在开始菜单中找到它,Linux用户可能需要额外安装这个组件(ubuntu下直接在终端中输入sudo apt-get install idle即可完成安装)。
打开IDLE,可以看到如下字符界面:
Python 3.4.3 (default, Oct 14 2015, 20:28:29) [GCC 4.8.4] on linux >>> #这个后面可以输入Python语句,回车便执行 >>> print("www."+"qingsword.com") #"加号"能将两段字符串连接起来,输出如下 www.qingsword.com
除了单行运行之外,点击IDLE菜单中的"File">"New File",会弹出一个新窗口,这个窗口同文本编辑器一样,可以输入任意多行代码,输入完成后点击菜单中的"Run">"Run Module"(或直接按F5),选择一个文件保存位置后,就会看到"Python Shell"中的执行结果。
上面我们已经大致了解了什么是Python,并且动手编写了第一个Python程序,然后用不同的方法去执行了这个程序,下面来看看Python中最核心的几个要素。
Python提供了几种不同的数据类型,本节仅介绍最常用的两种:int(整型)与str(字符串型)。
int(整型):Python所能表示的整数大小只受限与机器内存,而非固定的字节数。
例如:-999,1234567890,0。
str(字符串型):字符串型可以使用双引号或单引号封装,只要头尾使用的符号对称即可。
例如:"www.qingsword.com",'blog',"#$%©qingsword",""(空字符串,也可以使用单引号'')。
Python中可以使用[](方括号)来读取某段字符串中的单个字符,Python语法中,索引位置默认是从0开始的,下面是在IDLE中执行的几个例子:
#读取"www.qingsword.com"中第4个字符,因为索引是从0开始的,实际上读取的是这段字符串中的第5个,即"q" >>> "www.qingsword.com"[4] 'q' >>> "www.qingsword.com"[8] 's'
字符串和整数之间可以通过"datatype(item)"语法互相转换:
#字符串转换成整数时,字符串前后可以包含任意多个空格(字符串中间不能包含空格),并且被转换的字符串不能包含字母,否则会抛出异常 >>> int(" 123 ") 123 #将整数转换成字符串 >>> str(123) '123'
如果我们要储存某种数据类型,就要去定义可用于储存这些数据的"变量",但Python没有这种"变量",而是使用"对象引用"这一概念,下面在IDLE中用一个实例来解释什么是"对象引用":
#在Python中,操作符"="负责将等号前面的"对象引用"(x),与等号后在内存中的数据对象(red)进行绑定,x称之为red对象的引用,此时x保存的是red这个数据的内存地址,第三条语句z=x运行后,z与x指向的是同一个内存地址 >>> x="red" >>> y="yellow" >>> z=x >>> print(x,y,z) red yellow red #将y指向z所指向的内存地址,此时内存中的"yellow"数据对象没有任何"对象引用"指向它,它将被"垃圾回收程序"自动处理,消除这一部分的数据 >>> y=z >>> print(x,y,z) red red red
在Python中,整型与字符串都是固定类型,也就是说一旦创建了对象引用,就不能改变数据对象的值,如果想改变对象引用的值,就必须重新创建数据对象:
#使用操作符"="在内存中创建了一个数据对象3,并且将它关联到"对象引用"x上 >>> x=3 #此时如果将x重新使用操作符"="赋予数据对象4,实际上并不是去修改原本3所处的内存地址的数据,而是在内存中重新分配了一块区域并且储存了数据4,将x重新指向这个新的内存地址,3所在的内存地址如果没有任何对象引用,就将被回收清除,如果在此之前运行了y=x,那么3现在还有y指向它,所以不会被清除,整型和字符串都是如此 >>> x=4 >>> print(x) 4
Python提供了几种组合数据类型,本节仅介绍最常用的两种:元组与列表。
元组是固定的,创建后就不能改变;列表是可变的,在需要的时候,可以插入或移除数据;
下面是IDLE中创建元组和列表的几个简单实例:
#元组使用逗号创建,用逗号隔开元组中每个元素内容 >>> "www.qingsword.com","one","two","1234" ('www.qingsword.com', 'one', 'two', '1234') #将元组包含在一对小括号中也是可以接受的格式,如果小括号中仅包含一个元组元素,那么在这个元素末尾必须添加一个逗号 >>> ("www.qingsword.com",) ('www.qingsword.com',) #列表可以使用方括号来创建,用逗号隔开每个列表元素 >>> ["www.qingsword.com","one","two","three"] ['www.qingsword.com', 'one', 'two', 'three']
不论列表还是元组,都是储存在内存中的数据对象,我们可以给他们添加"对象引用"来调用他们:
>>> x=('a','b','c') >>> y=['d','e','f'] >>> print(x) ('a', 'b', 'c') >>> print(y) ['d', 'e', 'f']
元组、列表以及字符串等数据类型是"有大小的",我们可以使用len()函数来度量这些类型的"长度大小"(返回这些对象所包含的字符或元素的个数):
>>> x=('a','b','c') >>> y=['d','e','f'] >>> z="www.qingsword.com" #x和y分别包含三个元素,z被定义成字符串,其引用的字符串数据,一共有17个字符 >>> len(x) 3 >>> len(y) 3 >>> len(z) 17
Python使用"点"操作符来存取对象的某个属性,在上面的实例中,列表对象有多个属性,这些属性能够向列表添加、插入或删除元素:
#定义一个列表x,储存了6个整数 >>> x=[1,2,3,4,5,6] >>> print(x) [1, 2, 3, 4, 5, 6] #使用列表的append属性,向x列表添加一个7 >>> x.append(7) >>> print(x) [1, 2, 3, 4, 5, 6, 7] #使用remove属性,移除列表中的4 >>> x.remove(4) >>> print(x) [1, 2, 3, 5, 6, 7] #使用insert属性,像索引3的位置,插入一个整数4(索引是从0开始的,这就意味着,原本索引3的位置是整数5,现在在这个位置插入一个4,那么5的索引就要向后移动一位) >>> x.insert(3,4) >>> print(x) [1, 2, 3, 4, 5, 6, 7] #上面这三种方法都能够通过直接调用list来完成,因为list的append方法就等同于x的append方法,x就是列表对象,只不过使用list调用时,第一个传递的值需要是列表的"对象引用",list.append(列表对象引用名称,添加的数据),效果同上 >>> list.append(x,8) >>> print(x) [1, 2, 3, 4, 5, 6, 7, 8]
同字符串操作一样,可以使用方括号取出列表或元组中的元素值:
>>> x=["www.qingsword.com","qingsword","2016"] #语法:列表对象[索引值] >>> x[0] 'www.qingsword.com' >>> x[1] 'qingsword'
任何一门编程语言的基本功能都包含逻辑运算,Python提供了四种逻辑运算。
1)身份操作符is
用于判断其左边的对象引用与其右边的对象引用指向的是否为同一个内存地址,如果是,则返回True,否则返回False;
#虽然x和y都定义了相同的列表元素,但这两个列表的数据分别储存在内存的不同位置,所以他们不是同一个对象 >>> x=["www.qingsword.com"] >>> y=["www.qingsword.com"] >>> x is y False #手动将x指向y所对应的内存地址后,现在x和y指向了同一个内存地址,is返回True >>> x=y >>> x is y True #当这一现象出现在整数和字符串数据上时,结果就有点出乎意料,python很智能的将两个相同值的对象引用指向了同一个内存地址 >>> x=100 >>> y=100 >>> x is y True >>> x="abc" >>> y="abc" >>> x is y True #除了is外,我们还能使用is not来判断某个对象引用是不是不等于某个对象,本例首先将x赋予python内置的None对象(空对象),然后分别用is和is not操作符去判断 >>> x=None >>> x is None True >>> x is not None False
2)比较操作符
>>> a=1 >>> b=2 >>> c=3 #判断a是否小于b >>> a<b True #判断a是否大于b >>> a>b False #判断a是否等于b >>> a==b False #判断a是否不等于b >>> a!=b True #判断a是否大于或等于b >>> a>=c False #判断a是否小于或等于b >>> a<=c True #使用结链比较,c是否在1到4的闭区间里 >>> 1<=c<=4 True #字符串比较,字符串的每个字母都将转换成Unicode码,python会逐个比较这些Unicode码 >>> x="www.qingsword.com" >>> y="www.qingsword.com" >>> z="qingsword.com" >>> x==y True >>> x==z False
不要使用比较操作符去比较不同的数据类型,那样会产生一个TypeError的程序异常。
3)成员操作符in和not in
对字符串、列表或元组等数据类型,我们可以使用操作符in来测试成员关系,使用not in来测试非成员关系;
#x为简单的字符串对象引用,y为列表对象引用 >>> x="www.qingsword.com" >>> y=['a','b','c'] #判断单个字符'q'是否被包含在x中,答案是肯定的 >>> 'q' in x True >>> 'p' in x False #判断y中是否存在元素'b' >>> 'b' in y True >>> 'd' in y False
4)逻辑运算符
Python提供了三个逻辑运算符:and、or和not;其中and与or使用short-circuit逻辑,他们返回决定结果的操作数,而非布尔值;
short-circuit逻辑:
x and y,如果x为True,返回y,反之返回x;
x or y,如果x为True,返回x,反之返回y;
#任何非0的值,都相当于True >>> x=1 >>> y=0 #因为x为True,所以返回y的值 >>> x and y 0 #因为y为False,所以返回y的值 >>> y and x 0 #因为x是True,所以返回x的值 >>> x or y 1 #因为y是False,所以返回x的值 >>> y or x 1 #任何非空的字符串都代表True >>> x='abc' >>> y='123' >>> x and y '123' >>> x or y 'abc' #两个特殊情况,x为空字符串,相当于False >>> x='' >>> y='abc' >>> x and y '' #x为空对象,相当于False,返回空对象屏幕不会显示任何值 >>> x=None >>> y=1 >>> x and y
如果不使用流程控制语句,py文件中的语句都是按顺序从上往下逐行执行的,这一部分将介绍Python常用的四种流程控制语句。
1)if语句
if语句中可以有多个可选elif分支,最后的else分支也是可选的,请看下面的实例:
#!/usr/bin/env python3 #coding=utf-8 x=1000 if x<100: #如果x小于100,执行这个分支 print(x) elif x<1000: #如果x小于1000,执行这个分支 print(x) elif x<10000: #如果x小于10000,执行这个分支 print(x) else: #如果上面的条件都不匹配,执行这个分支 print(x) #不论执行的是哪个分支,这个程序都只是使用print()函数输出x的值
将上面的程序保存成后缀为.py的文件,然后执行它,就会看到控制台窗户返回一个值1000,而这个返回值实际上是由上面程序中第2个elif分支中的print()返回的,if语句有一个特点,从上往下匹配分支,不论哪个分支匹配到都执行分支下的语句,然后跳出整个if语句(也就是说,本例中,将不会去执行else分支进行判断了,如果第一个分支就匹配,那么后面的所有分支都不会被执行);
另外,请注意,python并没有C语言中的那种大括号来标明块结构,python标准规定,每层程序缩进块都使用"4个空格"(并非制表符),这就说明,每个if分支下面的语句,都比分支判断语句要缩进四个空格,在编写python的时候,尤其要注意这一点,很多专业的python文本编辑器都会将用户按下的tab键自动转换成4个空格,而其他的文本编辑器可能并不会这样做。
除了缩进外,大家可能注意到每个if分支后面都有一个说明号,这是必须的语法规定,刚开始可能非常不习惯。
2)while语句
while循环将会一直执行,直到while语句后面的表达式为False,或使用break跳出循环,请看下面的实例:
#!/usr/bin/env python3 #coding=utf-8 x=1 total=0 #while循环部分 #这个循环的判断条件将一直是True,如果不使用break跳出循环,将会永远循环下去 while True: if x<=100: #如果x小于或等于100 total+=x #total加上x的值 x+=1 #x递增1 continue #返回while开始处继续循环 else: #如果x大于100 break #跳出循环 #如果total不为0,输出total的值 if total: print(total)
执行这段程序,将返回5050,这是从1加到100的结果,上面这段while是为了演示continue和break的用法,实际上还有一种更加简单的方法来实现:
#!/usr/bin/env python3 #coding=utf-8 x=1 total=0 #当x大于100时将终止循环 while x<=100: total+=x x+=1 if total: print(total)
3)for...in语句
下面是一个判断元音/辅音字母的小程序:
#!/usr/bin/env python3 #coding=utf-8 #abc对象引用指向了一个包含26字母的字符串 abc="ABCDEFGHIJKLMNOPQRSTUVWXYZ" #使用for循环逐个读取abc字符串中的单个字符 for x in abc: if x in "AEIOU": #如果读取出来的字符是"AEIOU"中的一个,说明这个字母是元音字母 print(x,"是元音字母") else: print(x,"是辅音字母")
大家可以尝试着运行这个程序,会的到26条返回结果,每条结果都会包含一条语句诸如:"A 是元音字母"。
4)try基本异常处理语句
基本异常处理也是流程控制的一部分,当程序中遇到异常时,会被try语句捕获,并跳转到对应的异常处理分支:
#!/usr/bin/env python3 #coding=utf-8 #input()函数允许读取用户键盘数据流,本例读取这些数据保存在内存中,并用s对象指向 s=input("请输入一个整数:") #将可能发生异常的语句包含在try语句结构中,将s对象对应的值转换成整型,如果输入的是一个不可转换的字符串,就会抛出ValueError异常,并跳转到下面的except分支,except分支下面只有一条指令,打印出异常的内容(ValueError as erro语句将这个被捕获的ValueError异常的输出信息赋值给erro这个对象,erro对象包含了这次异常所有的输出信息) try: i=int(s) print("您输入的整数为:",i) except ValueError as erro: print(erro)
运行这个程序,如果输入的是字符串,例如:
请输入一个整数:xxx #将返回下面这样的异常信息 invalid literal for int() with base 10: 'xxx'
python提供了完整的运算符,包括四则运算操作符(+,-,*,/)以及增强的四则运算操作符(+=,-=,*=,/=);
与其他编程语言唯一的区别是对除法的处理,python的除法操作符会产生一个浮点数,而不是整数(就算整除,也会产生一个浮点数),如果需要产生一个整数,需要使用int()函数转换,或使用双斜杠(//剥离操作符);
下面是IDLE中这些算数操作符的几个实例:
>>> 1+1 2 #使用增强四则运算符 >>> a=1 >>> a+=1 >>> print(a) 2 >>> a*=6 >>> print(a) 12 #所有的除法都会返回一个浮点数 >>> 4/2 2.0 >>> 2*2 4 >>> 13/6 2.1666666666666665 #使用剥离操作符或者使用整型转换函数将舍去小数点后面的部分 >>> 13//6 2 >>> int(13/6) 2
前面已经介绍过,整数和字符串对象引用的数据都是固定的,这就意味着对一个"对象引用"使用四则运算后,实际上是在内存中重新划分了一块区域来储存计算结果,然后将"对象引用"重新指向这个结果的内存地址。
在字符串和列表的操作中,python重载了运算符+和+=,请看下面的实例:
>>> x="abc" #仅仅使用加号,将x指向的值与"def"连接起来输出,x值不变 >>> x+"def" 'abcdef' >>> print(x) abc #如果使用+=,则是将def追加到abc后,x值改变 >>> x+="def" >>> print(x) abcdef #对列表使用+=操作符,可以直接追加列表元素(可以一次性追加多个,用逗号隔开) >>> y=["a","b","c"] >>> y+=["d"] >>> print(y) ['a', 'b', 'c', 'd'] #如果对列表追加元素时没有添加中括号,python会将追加的内容每个字符拆开,作为单个元素,逐个添加到列表中 >>> y+="qing" >>> print(y) ['a', 'b', 'c', 'd', 'q', 'i', 'n', 'g']
Python提供了内置的input()函数,用来接收用户键盘输入的数据,这个函数需要一个可选的字符串参数,用来打印在屏幕上,提示用户要输入的数据,之后等待用户输入完成并按回车键结束输入(或使用return键来终止输入),如果用户不输入任何文本直接敲击回车键,input()函数会返回一个空字符串,下面用一个实例来演示input()函数:
#!/usr/bin/env python3 #coding=utf-8 print("请输入整数,或直接输入回车结束输入;") total=0 count=0 #进入while循环,只有当用户直接回车时才会执行if语句中的else分支,跳出循环 while True: #input将用户输入保存在内存中,并用s对象指向 s=input("请输入一个整数:") if s: #如果用户直接回车input会返回一个空字符串,if的判断会是False try: #为了防止用户输入一个非数字,导致int()转换出现异常 i=int(s) except ValueError as erro: #捕获异常 print(erro) total+=i #将用户输入累加到total中 count+=1 #计数器递增1 else: break #如果用户没有输入任何数字直接回车,count值为0,print不会被执行,否则输出count数,total总数,最后输出这些数的平均值 if count: print("count=",count,"total=",total,"mean=",total/count)
将上面的程序保存为py文件,并且执行,下面是执行结果:
请输入整数,或直接输入回车结束输入; 请输入一个整数:1 请输入一个整数:2 请输入一个整数:3 请输入一个整数:4 请输入一个整数:3 请输入一个整数:2 请输入一个整数:1 请输入一个整数:#回车退出循环 count= 7 total= 16 mean= 2.2857142857142856
对于上面这个小程序,有第二种实现方法,这一次不是按回车让循环退出,而是使用try捕获EOFError异常,这意味着(linux或unix)用户按下了ctrl+d组合键(在windows中需要按下ctrl+z并按enter键),当用户按下组合键时跳出循环,请看下面的实例:
#!/usr/bin/env python3 #coding=utf-8 print("请输入整数,或按ctrl+d(linux)/ctrl+z(windows)结束输入;") total=0 count=0 #程序的流程和上面那个相同,唯一的不同是,这个循环中,try新增了一个异常捕获分支,当用户按下ctrl+d组合键后,将会触发EOFError异常,执行break跳出循环 while True: try: s=input("请输入一个整数:") if s: i=int(s) count+=1 total+=i except ValueError as erro: print(erro) except EOFError: break if count: print("count=",count,"total=",total,"mean=",total/count)
python中允许使用def语句来封装函数,def是一条与赋值操作符工作方式类似的语句,执行def时,会创建一个函数对象,同时创建一个带有指定名的对象引用,请看下面的实例:
#!/usr/bin/env python3 #coding=utf-8 #-------- #用来获取用户输入的年龄 def get_age(msg): #当用户输入了一个错误的值,会重新循环,当用户输入了一个正确的int值,会调用return,将输入的值返回给函数的调用者,并终止函数的执行 while True: try: i=int(input(msg)) return i except ValueError as err: print(err) #-------- #调用函数,括号中的字符串会传递给函数的msg age=get_age("请输入您的年龄:") #打印出用户输入的值 print(age)
除了函数外,我们还会经常见到在程序的开始处用import语句导入某些模块,这些模块文件包含了许多自定义的函数,提供了一些常见的功能,下面用python自带的random模块(该模块在python标准库中,全名是random.py)举例:
#!/usr/bin/env python3 #coding=utf-8 #导入random模块,虽然标准库中random模块是有后缀py的,但是在使用import导入时不需要携带后缀,这个模块提供了一些随机数选择器 import random #从1到100中随机选择一个整数,用x指向这个随机数 x=random.randint(1,100) #从后面的列表中随机选择一个元素,用y指向这个元素 y=random.choice(["a","b","c","d","e","f"]) #打印出这两个随机选择的值 print(x,y)