1.1 Python是什么
相信混迹IT界的很多朋友都知道,Python是近年来最火的一个热点,没有之一。从性质上来讲它和我们熟知的C、java、php等没有什么本质的区别,也是一种开发语言,而且已经进阶到主流的二十多种开发语言的top 5(数据源自最新的TIOBE排行榜)。
来头不小啊!二十多种主流的开发语言,我该从哪一个开始呢?人生苦短,let‘s python!
1.2 Python的由来和发展趋势
Python的前世源自鼻祖“龟叔”。1989年,吉多·范罗苏姆(Guido van Rossum)在阿姆斯特丹为了打发无聊的圣诞节,决心开发一个新的脚本解释程序,自此Python和创始人“龟叔”开始进入公众视野。他希望这个新的叫做Python的语言,能符合他的理想:创造一种C和shell之间,功能全面,易学易用,可拓展的语言。
1991年,第一个Python编译器诞生。它基于C语言实现,并能够调用C语言的库文件。后面历经版本的不断换代革新,Python走到了非常具有里程碑意义的一个节点,即2004的2.4版本诞生了目前最流行的WEB框架Django!六年后Python发展到2.7版本,这是目前为止2.x版本中最新且较为广泛使用版本。
2.7版本的诞生不同于以往2.x版本的垂直换代逻辑,它是2.x版本和3.x版本之间过渡的一个桥梁,以便最大程度上继承3.x版本的新特性,同时尽量保持对2.x的兼容性。
因此3.x版本在2.7版本之前就已经问世,从2008年的3.0版本开始,python3.x系呈迅猛发展之势,版本更新活跃,一直发展到现在最新的3.5.2版本。3.5版本也是目前3.x系列中主流且广泛使用的版本,后续相关程序的demo,默认均基于3.5版本展开。
1.3 Python 2 VS Python 3
许多初学者会纠结于从2.x版本还是3.x版本开始python学习之路。这里简要对比下个人学习了解到的两者的差异:
3.x版本中 PRINT IS A FUNCTION,使用起来更简单方便;
3.x版本中默认使用unicode编码,妈妈再也不用担心你的程序编码问题了;
3.x版本中某些库进行了改名,具体还有待在后续学习中深入展开;
目前3.x版本还不能完全支持Twisted module,这恐怕是3.x版本中最大的遗憾。也不要过于纠结这点,据说官方正在弥补这个不足,同时也相信能有办法解决的:)
In summary : Python 2.x is legacy, Python 3.x is the present and future of the language. 长江后浪推前浪,python的未来是属于3.x系列的,官方宣布2020年之后不再支持2.x系列中最nb的2.7版本,2.x版本将逐渐寿终正寝,最终被铭刻在开发语言的丰碑上。
所以学习3.x版本没错的!
1.4 Python的优缺点
二十多种主流开发语言,python何以能在20多年间以如此迅猛之势横扫七大洲八大洋呢?这都是它自身优良的特性决定的.
Python优点:
1.“优雅”、“明确”、“简单”
这是python的定位,使得python程序看上去简单易懂,初学者容易入门,学习成本更低。但随着学习的不但深入,python一样可以满足胜任复杂场景的开发需求。引用一个说法,Python的哲学是就是简单优雅,尽量写容易看明白的代码,尽量写少的代码。
2. 开发效率高
python作为一种高级语言,具有丰富的第三方库,官方库中也有相应的功能模块支持,覆盖了网络、文件、GUI、数据库、文本等大量内容。因此开发者无需事必躬亲,遇到主流的功能需求时可以直接调用,在基础库的基础上施展拳脚,可以节省你很多功力和时间成本,大大降低开发周期。
3. 无需关注底层细节
Python作为一种高级开发语言,在编程时无需关注底层细节(如内存管理等)。
4. 功能强大
Python是一种前端后端通吃的综合性语言,功能强大,php能胜任的角色它都能做,至于后端如何胜任,需要在后续学习中逐步领悟。
5. 可移植性
Python可以在多种主流的平台上运行,开发程序时只要绕开对系统平台的依赖性,则可以在无需修改的前提下运行在多种系统平台上,具体有待后续学习中深入展开。其他优点有待继续发掘。
一个硬币总有两面,那么Python有缺点吗?答案是肯定的,总结如下:
Python缺点:
1. 代码运行速度慢
因为Python是一种高级开发语言,不像c语言一样可以深入底层硬件最大程度上挖掘榨取硬件的性能,因此它的运行速度要远远慢于c语言。另外一个原因是,Python是解释型语言,你的代码在执行时会一行一行地翻译成CPU能理解的机器码,这个翻译过程非常耗时,所以很慢。而C程序是运行前直接编译成CPU能执行的机器码,所以非常快。
但需要注意的是,这种慢对于不需要追求硬件高性能的应用场合来讲根本不是问题,因为它们比较的数量级根本不是用户能直观感受到的!想想程序执行所需的时间数量级?例如开发一个下载MP3的网络应用程序,C程序的运行时间需要0.001秒,而Python程序的运行时间需要0.1秒,慢了100倍,但由于网络更慢,需要等待1秒,用户体验几乎没有差别,除非你用非常精确的计时器来计时。
2. 发布程序时必须公开源代码
什么?有没有搞错?是的,发布程序时我们必须公开源代码!还是因为Python是一种解释性语言,没有编译打包的过程(据说最新的python可以打包,但本质上还是把源代码和解释器打在一起,没有太大实际意义)。想想我们的shell脚本是不是也是这个情况,你能在不发布源代码的情况下发布一个黑盒子程序来让别人正常使用么?
这个缺点仅限于你想单纯靠卖开发出来的软件产品挣钱的时候。但在这个开发互联的时代,不靠卖产品本身来赚钱的商业模式越来越主流了,所以问题也不是没法解决。
总结起来,Python的优点多于缺点,而且缺点在多数它能胜任的情况下不是根本性问题,瑕不掩瑜,尽情享受它给我们带来的乐趣和便利吧!
1.5 Python的适用领域
Python典型的适用领域如下:
1. 云计算开发
云计算领域最火的语言,典型代表openstack。
2. web开发
众多优秀的web框架,众多优秀的大型web站点(Youtube,instagrm,豆瓣等)均基于python开发。
3. 系统运维
各种自动化工具的开发,CMDB、监控告警系统、堡垒机、配置管理&批量分发工具等均可以搞定。这是自己需要重点学习的领域。
4. 科学计算、人工智能
据网上了解用于围棋大战的谷歌阿发狗就使用了python开发(但估计只是部分而已)。
5. 图形GUI处理
暂时没多少体会,后续领悟吧。
6. 网络爬虫
不知道给网络爬虫单独归类是否合适,姑且这样吧。这年头网络爬虫无处不在,很多都是基于python开发,包括谷歌的爬虫。估计这是爬虫工程师的必备工具吧。
1.6 哪些地方在用Python
来几个鲜活的知名公司应用案例,以示敬意:
谷歌:Google app engine、google earth、爬虫、广告等
Youtube: 世界最大的在线视频网站基于python开发,好强大
Instagram:美国最大的图片分享网站,全部基于python开发
facebook:大量的基础库基于python开发
Redhat:yum包管理工具基于python开发
国内知名互联网公司的应用:豆瓣、知乎的网站,还有很多主流的互联网公司(阿里、腾讯、百度、金山、搜狐、盛大、网易、新浪、网易、果壳、土豆等)通过python来完成各种任务。
2.1 编程开发规范
作为一门开发语言,python自然也有自己的编程规范,以下是特有且必须遵循的规范:
1. 代码开头
python中代码必须顶格编写,除非被作为语句嵌套在条件判断或条件循环中。
2. 代码层级
代码与代码之间的逻辑层级关系(涉及逻辑判断、包含关系等情况)通过空格来界定,第一层顶格编写,第二层(被包含或者逻辑判断后的执行动作)开头预留4个空格(如果不考虑跨平台可以使用tab)
3. 对齐方式
同一个层级的代码必须严格对齐,如第一层都是顶格,第二层都是4个空格开头,第三层则是8个空格,以此类推。
4. 注释
单行注释用#开头,单独一行作为注释或者在代码后面通过#跟上注释均可,多行注释在首尾处用成对的三引号引用即可,可以是成对的三个单引号或者三个双引号。
5. 代码块
目前来看if逻辑判断和for循环条件后面均以冒号结尾,然后通过4个空格开始下一层级的实际执行动作语句编写。这部分在冒号后面接上的语句称为代码块。
6. 程序命名
编写的python程序必须以.py结尾。
7. 项目规范
启动一个项目开发时先在开发工具中创建project,然后根据需要创建目录,最后在目录下创建当前活动的py程序。
2.2 变量
python中的变量也用于存储临时值以便后续灵活调用,在定义时只能使用字母、数字、下划线的任意组合,且不能以数字开头,不能以python内置的关键字来命名变量(如and,import,global,finally等,有待后续学习加深印象)。对变量进行字符串类型的赋值时,字符串需要用成对的引号引起来,可以是单引号、双引号或者三引号。
建议通过以下两种形式来定义较为复杂的变量,便于阅读:
1. 驼峰体
即每个单词的首字母大写,其他小写,如MappingTable
2. 下划线
不同单词之间通过下划线分开,如mappting_table
2.3 字符编码
字符编码经历了ASCII码->unicode->UTF-8的演变过程,python 2.x默认使用ASCII编码,而3.x默认使用UTF-8编码。由于字符编码事关重大,一言不合就会导致乱码,因此强烈建议统一使用万用的utf-8编码。怎么使用呢?
1. 程序开头明确显式定义
1
2
|
#!/usr/bin/env python # -*- coding: utf-8 -*- |
windows下编程可忽略第一行,但为了保留移植性建议始终声明变量。
2. 在程序解释器中选择utf-8字符编码
以上两个条件缺一不可,虽然python 3.x版本默认使用utf-8编码,但还是建议在程序中声明编码格式。
以上是结果,下面谈谈为什么强烈建议使用urf-8编码,以及为什么utf-8编码就可以通吃。
众所周知计算机是美国人发明的,因此最早就只有包括所有字母的大小写、数字、必要的特殊符号等合计才127个字符被编码到计算机里,这个编码就是ASCII编码。由于需要进行编码的字符才有127个,因此用7个二进制位就足以搞定了,但8个二进制位才能构成一个完整的字节,因此索性用8个二进制位来进行编码,剩余的一位只好浪费掉。所以ASCCI码只占用一个字符。
随着计算机技术的推广和普及,其他不以英语为官方语言的国家也开始使用计算机了。那么现在问题来了,一个字节的8个bit位只能表示非常有限的字符(设计时只包括所有字母的大小写、数字、必要的特殊符号,其中整数还不能超过255),既有的ASCII编码表里没有包含其他国家的语言字符,但显然也没法强迫全球都使用英语,于是各个国家开始进行本土化改良,设计能满足自己国家需要的编码,如国内的GB2312。这里的改良涉及两个要点,一是原有的一个字节的编码空间要扩充为两个字节甚至更多,二是新的编码还不能与既有的ASCII编码冲突,否则老美要跟你捉急了!你可以想象,中国搞定了一套,日本也搞定了一套,接着是韩国、越南等巴拉巴拉,大家都有自己的编码标准,各自为政,遇到多语言混合使用的场景这编码表还不炸开锅,连同计算机一起傻掉!这时Unicode应运而生。Unicode把所有语言都统一到一套编码里,用两个甚至更多的字节来进行编码(通常用两个字节,搞不定时再喊人加砝码呀),这样就不会再有乱码问题了。
Unicode搞定了多国语言乱码和编码统一的问题,但你会发现如果需要处理的内容全部是英文的话,用Unicode编码比ASCII编码需要多一倍的存储空间,在存储和传输上就不太经济划算。OK,Unicode的演进改良版utf-8就是来解决这个问题的。utf-8的优势在于它使用“可变长编码”,在继续沿用ASCII编码基础上来对1个字节不能搞定的那些语言字符进行编码设计,这样英文还是用1个字节,遇到中文就用3个或者更多的字节来处理。这样既可以保障空间和性能的最大化,还能兼顾老美的老巢和其他非英文的编码兼容问题,一举三得!所以你会发现ASCII其实是utf-8的子集,utf-8向下兼容。
2.4 Python解释器
python是一门解释性语言,自然不能缺了解释器(类似于JVM)。官方支持Cpython、Jpython、Ironpython和pypy等,默认使用基于C语言实现的Cpython。它也是最为广泛使用的解释器。程序运行时会把.py文件转换成.pyc字节码文件,然后运行在python虚拟机上。
2.5 构建Python的开发环境
构建好包括解释器(虚拟机)和开发工具IDE在内的Python的开发环境才便于展开程序开发之旅。
其中解释器(虚拟机)从python官方下载安装即可,需要注意的是建议安装3.5版本,windows下安装后需要把python的bin目录和scripts目录追加到系统环境变量path和用户变量path中。我的win 7用户不是以administor,补充追加了用户变量后才能在cmd下傻瓜式地输入python。linux下系统默认是2.x的版本,安装3.5版本时需要先将旧版本重命名为其他目录(如python2.6)后再安装,安装完毕无需额外设置环境变量。
好的程序猿都得有自己好使的IDE,python程序建议使用pycharm工具来进行开发。从官网下载安装社区版即可,需要注意的是选择后本地的解释器和项目的默认字符编码。其他一些好玩的特性、快捷键等只有后续逐步体会了。
2.6 模块初识
python内置了很多模块,同时也可以自定义编写一些好玩的模块,使用模块时需要通过关键字import导入。导入后python会从系统变量的路径中从前往后一次查找,首次成功查找匹配后不再进行后续查找。因此如果需要使用自定义模块,需要特别关注自定义模块的存放位置,底线是只存放在系统变量的一个路径下,否则可能得到意外的结果。
系统变量的路径可通过以下方式查看:
以上是windows下3.5版本的输出结果,linux平台或者其他版本的输出有所差别,以实际为准。
2.7 用户输入和格式化输出
用户输入通过input来实现,示例如下:
YourName=input("Please input you name here: ")
简单的输出通过print来实现,示例如下:
print("Hi,", YourName) #调用输出上面用户输入的变量YourName
注意:
1. 3.x版本中input默认接收用户输入的类型为字符串,如果需要使用其他的数据类型则需要进行转换,如 UserAge=int(input("Please input your name:"))
2. print输出中可以接上转义符号来实现更多的输出显示效果,如 表示换行, 为制表符。
print的使用进阶——字符串的格式化输出:
python中,对字符串进行格式化输出与c语言是相同的,即借助%来实现。%s表示与字符串替换,%d表示用整数替换,%f表示用浮点数替换,如果输出的字符串中本身就需要%(比如输出比率),则需要用连续的两个%%来输出%。
示例程序如下:
1
2
3
4
5
|
#!/usr/bin/env python #-*- coding:utf-8 -*- print ( "Your name is %s" % "Bob" ) print ( "Your age is %d" % 21 ) print ( "Your name is %s,age is %d" % ( "Bob" , 21 )) |
从以上示例程序可看出,利用print进行格式化输出的基本格式是在需要替换输出的位置用%s,%d等占位符,然后在后面通过%来接上实际替换后需要输出的内容,如果需要替换输出的元素不止一个,则需要在%后面通过一对圆括号把实际替换后需要输出的内容包含进来,同时在每个元素之间用逗号隔开。
2.8 Python的运行逻辑
Python的运行工作逻辑如下:
内存加载代码->语法分析->解释器加载->生成字节码->执行字节码->生成机器码->CPU执行
3.1 第一个Python程序--HelloWorld
python的第一个程序也从hello world开始把:
1
2
3
|
#!/usr/bin/env python #! -*- coding:utf-8 -*- print ( "Hello world!" ) |
执行结果:
"C:Program FilesPython35python.exe" D:/python/Day1/test/HelloWorld.py
Hello world!
Process finished with exit code 0
3.2 If-else判断
3.2.1 If-else语法规范
以下是if-else判断的语法结构规范
1
2
3
4
5
6
7
8
|
if condition1: command_layer1_1 if condition2: command_layer2_2 else : command_layer2_2 else : command_layer1_2 |
3.2.2 示例程序
以下为一个演示两层if-else循环的程序:
1
2
3
4
5
6
7
8
9
10
11
|
#!/usr/bin/env python #顶格编写 #! -*- coding:utf-8 -*- user_input = input ( "Please input you username:" ) if user_input = = "Bob" : #注意这里的冒号结尾 passwd_input = input ( "Please input your password:" ) #注意从这里开始,第一个if条件为真时需要执行的动作语句均需要左缩进4个空格 if passwd_input = = "password" : #第一个if下的第二个if,仍然要左缩进4个空格,同时冒号结尾 print ( "Welcome login,%s!" % user_input) #第二层if条件为真时执行的动作语句,需要在第一层语句基础上再缩进4个空格,因此需要缩进8个空格 else : #第二层if-else中的else,因此需要与第二层if对齐,缩进4个空格 print ( "Invalid username or password, please check your input" ) #第二层if-else条件为假时执行的动作语句,同样需要与第二层if一样缩进8个空格 else : #第一层if-else中的else关键字,顶格冒号结尾 print ( "Invalid username or password, please check your input" ) #第一层if-else判断条件为假时执行的动作,与第一层if一样需要缩进4个空格 |
说明:该示例程序仅为演示多层if-else的语法结构,程序本身的设计存在漏洞;空格缩进在pycharm IDE环境中会被自动处理,但在普通文件编辑器中需要手动设置。
以下为改良版示例程序,通过引入对if的多条件判断来避免上述程序的漏洞:
1 #!/usr/bin/env python 2 #! -*- coding:utf-8 -*- 3 username=input("Please input you username: ") 4 passwd=input("Please input you password: ") 5 if username == "Bob" and passwd == "password": 6 print("Welcome login, %s!" %username) 7 else: 8 print("Invalid username or password, please check your input!")
此时只有用户名和密码同时输入正确了才会给出相应提示,否则均提示口令无效,避免暴力破解。
3.2.3 if-elif-else扩展
上述判断均为单一式的if-else判断,以下为if-elif-else的判断扩展:
语法结构:
1
2
3
4
5
6
7
8
|
if condition1: command1 elif condition2: command2 elif condition3: command3 else condition4: command4 |
不过这种结构仅仅适用于单一条件存在多种case情况下,语法结构看起来还是比较简单,当然顶格、左缩进4个空格和冒号这些规范一样要遵循。
还是来一个示例程序加深理解:
1
2
3
4
5
6
7
8
9
|
#!/usr/bin/env python #! -*- coding:utf-8 -*- age = int ( input ( "Please input your age
" )) if age > = 18 : print ( "Oh, you're an adult
" ) elif age > = 6 : print ( "Ha, you're a teenager
" ) else : print ( "Come on, little kid!
" ) |
3.3 For循环
3.3.1 for循环语法规范
For循环的基本语法规范是:
1
2
|
for variable in XXX: loop command |
其中variable表示命名的变量,一般程序中使用i,j等等,XXX表示变化的范围,可以是list列表,一般会考虑使用range函数,来表示一个整数序列,如range(5)就表示小于5的整数序列,即0-4。 语法规范中同样需要for语句后面的结尾冒号,以及循环体中的4个空格的左缩进。
3.3.2 示例程序
猜数字游戏,通过系统生成一个随机数作为预设年龄,对用户提供3次猜的机会,前两次如果没有猜中给出数字范围大小的提示,如果第3次还没有猜中则给予鼓励提示,同时打印出这个预设的数字,当然三次当中有任何一次猜中会给用户猜中提示的:
1 #!/usr/bin/env python 2 #! -*- coding:utf-8 -*- 3 import random #导入随机数模块 4 Age=random.randrange(10)#随机生成一个小于10的整数(0-9,不包括负数),并赋值给Age 6 for i in range(3): 7 if i < 2: 8 guess_number=int(input("Please input the age of my dog you guess: ")) 9 if guess_number > Age: 10 print("The age you guess is a little big, think smaller! ") 11 elif guess_number < Age: 12 print("The age you guess is a little small, think bigger! ") 13 else: 14 print("Bingo, you got the number,congratulations! ") 15 break 16 else: 17 guess_number=int(input("Please input the age of my dog you guess: ")) 18 if guess_number == Age: 19 print("Bingo, you got the number,congratulations! ") 20 else: 21 print("Oh,you just got bad luck, come to try again, you can do it! The actual age of my dog is %d... "% Age)
注意:
1.为便于程序调试可先对Age赋值固定的数字
2.前两次如果猜中了就需要退出循环,这里使用了break关键字,意思是跳出整个循环,与之相对应的还有continue关键字,用于跳出当次循环,二者的使用区别还有待进一步深入学习
OK,现在来改进下程序, 当用户连续三次猜错后继续给机会,让用户选择是继续猜还是直接退出,如果继续则再一次获得三次猜的机会,如此循环下去。还是用for循环吧:
1 #!/usr/bin/env python 2 #! -*- coding:utf-8 -*- 3 Age=22 4 counter=0 5 for i in range(10): 6 if counter < 3: 7 guess_number=int(input("Plese input your guess number: ")) 8 if guess_number == Age: 9 print("You got the number, congratulations!") 10 break 11 elif guess_number > Age: 12 print("The number you guessed is too big, guess a smaller one ") 13 else: 14 print("The number you guessed is too small, guess a bigger one ") 15 counter += 1 16 elif counter == 3: 17 continue_flag=input("Do you want to continue? Please type Y to continue or N to quit: ") 18 if continue_flag == "Y": 19 counter = 0 20 else: 21 print("Bye") 22 break 23 else: 24 print("You've tried too many times.")
这里为了保证每一个轮回中的第四次(上述程序中的第四次和第八次)能让程序继续循环,引入了另外一个变量来进行计数并重置。把for循环换作while循环看起来差不多:
1 #!/usr/bin/env python 2 #! -*- coding:utf-8 -*- 3 Age=22 4 i=0 5 counter=0 6 while counter < 10: 7 if i < 3: 8 guess_number=int(input("Plese input your guess number: ")) 9 if guess_number == Age: 10 print("You got the number, congratulations!") 11 break 12 elif guess_number > Age: 13 print("The number you guessed is too big, guess a smaller one ") 14 else: 15 print("The number you guessed is too small, guess a bigger one ") 16 i += 1 17 else: 18 continue_flag=input("Do you want to continue? Please type Y to continue or N to quit: ") 19 if continue_flag == "Y": 20 i = 0 21 else: 22 print("Bye") 23 break 24 counter +=1
1. Python是一门主流且发展迅猛的开发语言,目前存在2.x和3.x两个版本分支,前端后端都能胜任,功能强大,在互利网公司应用广泛,值得托付;
2. Python程序的开发需要安装解释器和IDE,建议使用pycharm,2.x和3.x下的默认字符编码不同,永远推荐使用utf-8编码,包括程序编码和解释的编码两个层面;
3. 系统自带模块和自定义编写的模块均可以通过import导入使用;
4. 在进行python程序开发时,注意代码需要分层体现,第一层代码顶格编写,第二层(用在第一次出现的流程控制语句中的代码块)左缩进4个空格;
5. input用于接收用户输入,默认输入的数据类型是字符串,可通过int关键字转换为整数。print可进行简单输出,如要格式化输出则需要借助%s %d %f等来实现,具体视数据类型而定;
6. 流程控制语句if-else判断和for、while循环都需要注意代码书写格式,流程控制语句关键字一定是以冒号结尾,具体的流程控制代码块则需要左缩进处理,第一层左缩进4个空格,第二层8个空格,以此类推;
7.continue和break可分别用于退出当前(当次)流程控制和整个循环,课堂上演示了在for循环中的使用,在if-else判断中不能使用。