强大自己是唯一获得幸福的途径,这是长远的,而非当下的玩乐!
1. Python 出身
python的创始人为吉多·范罗苏姆(Guido van Rossum),python是人在1989年圣诞为了打发时间,开发而出的一个新的脚本解释程序,下图为python全球排行榜,图为2018年10月数据。
图片来源:https://www.tiobe.com
2. python发展史
-
1989年,为了打发圣诞节假期,Guido开始写Python语言的编译器。Python这个名字,来自Guido所挚爱的电视剧Monty Python’s Flying Circus。他希望这个新的叫做Python的语言,能符合他的理想:创造一种C和shell之间,功能全面,易学易用,可拓展的语言。
-
1991年,第一个Python编译器诞生。它是用C语言实现的,并能够调用C语言的库文件。从一出生,Python已经具有了:类,函数,异常处理,包含表和词典在内的核心数据类型,以及模块为基础的拓展系统。
-
Granddaddy of Python web frameworks, Zope 1 was released in 1999
-
Python 1.0 - January 1994 增加了 lambda, map, filter and reduce.
-
Python 2.0 - October 16, 2000,加入了内存回收机制,构成了现在Python语言框架的基础
-
Python 2.4 - November 30, 2004, 同年目前最流行的WEB框架Django 诞生
-
Python 2.5 - September 19, 2006
-
Python 2.6 - October 1, 2008
-
Python 2.7 - July 3, 2010
-
In November 2014, it was announced that Python 2.7 would be supported until 2020, and reaffirmed that there would be no 2.8 release as users were expected to move to Python 3.4+ as soon as possible
-
Python 3.0 - December 3, 2008
-
Python 3.1 - June 27, 2009
-
Python 3.2 - February 20, 2011
-
Python 3.3 - September 29, 2012
-
Python 3.4 - March 16, 2014
-
Python 3.5 - September 13, 2015
-
Python 3.6 - December 16,2016
3. 语言分类
编译器是把源程序的每一条语句都编译成机器语言,并保存成二进制文件,这样运行时计算机可以直接以机器语言来运行此程序,速度很快;
而解释器则是只在执行程序时,才一条一条的解释成机器语言给计算机来执行,所以运行速度是不如编译后的程序运行的快的.
这是因为计算机不能直接认识并执行我们写的语句,它只能认识机器语言(是二进制的形式)
3.1 编译型
优点:编译器一般会有预编译的过程对代码进行优化。因为编译只做一次,运行时不需要编译,所以编译型语言的程序执行效率高。可以脱离语言环境独立运行。
缺点:编译之后如果需要修改就需要整个模块重新编译。编译的时候根据对应的运行环境生成机器码,不同的操作系统之间移植就会有问题,需要根据运行的操作系统环境编译不同的可执行文件。
3.1.2 解释型
优点:有良好的平台兼容性,在任何环境中都可以运行,前提是安装了解释器(虚拟机)。灵活,修改代码的时候直接修改就可以,可以快速部署,不用停机维护。
缺点:每次运行的时候都要解释一遍,性能上不如编译型语言。
3.2.1 动态类型语言
动态类型语言是指在运行期间才去做数据类型检查的语言,也就是说,在用动态类型的语言编程时,永远也不用给任何变量指定数据类型,该语言会在你第一次赋值给变量时,在内部将数据类型记录下来。Python和Ruby就是一种典型的动态类型语言,其他的各种脚本语言如VBScript也多少属于动态类型语言。
3.2.2 静态类型语言
静态类型语言与动态类型语言刚好相反,它的数据类型是在编译其间检查的,也就是说在写程序时要声明所有变量的数据类型,C/C++是静态类型语言的典型代表,其他的静态类型语言还有C#、JAVA等。
3.3.1 强类型定义语言
强制数据类型定义的语言。也就是说,一旦一个变量被指定了某个数据类型,如果不经过强制转换,那么它就永远是这个数据类型了。举个例子:如果你定义了一个整型变量a,那么程序根本不可能将a当作字符串类型处理。强类型定义语言是类型安全的语言。
3.3.2 弱类型定义语言
数据类型可以被忽略的语言。它与强类型定义语言相反, 一个变量可以赋不同数据类型的值。
强类型定义语言在速度上可能略逊色于弱类型定义语言,但是强类型定义语言带来的严谨性能够有效的避免许多错误。另外,“这门语言是不是动态语言”与“这门语言是否类型安全”之间是完全没有联系的!
python是一门动态解释性的强类型定义语言
4. Python种类
CPython
当我们从Python官方网站下载并安装好Python 3.6后,我们就直接获得了一个官方版本的解释器:CPython。这个解释器是用C语言开发的,所以叫CPython。在命令行下运行python
就是启动CPython解释器。
CPython是使用最广的Python解释器。
IPython
IPython是基于CPython之上的一个交互式解释器,也就是说,IPython只是在交互方式上有所增强,但是执行Python代码的功能和CPython是完全一样的。好比很多国产浏览器虽然外观不同,但内核其实都是调用了IE。
CPython用>>>
作为提示符,而IPython用In [
序号
]:
作为提示符。
PyPy
PyPy是另一个Python解释器,它的目标是执行速度。PyPy采用JIT技术,对Python代码进行动态编译(注意不是解释),所以可以显著提高Python代码的执行速度。
绝大部分Python代码都可以在PyPy下运行,但是PyPy和CPython有一些是不同的,这就导致相同的Python代码在两种解释器下执行可能会有不同的结果。如果你的代码要放到PyPy下执行,就需要了解PyPy和CPython的不同点。
Jython
Jython是运行在Java平台上的Python解释器,可以直接把Python代码编译成Java字节码执行。
IronPython
IronPython和Jython类似,只不过IronPython是运行在微软.Net平台上的Python解释器,可以直接把Python代码编译成.Net的字节码。
5. 编码
由于计算机数据最底层传输的是01101001001数据,所以为了能对数据进行展示,则需要有一个对照,如01000001对应大写字母A,这样当数据传输至我们的计算机时,按照对应的对照表,把信息显示,则变成我们能够看懂的信息。以下列举一些对照表并做相应解释。
ASCII
ASCII(American Standard Code for Information Interchange,美国标准信息交换代码)是基于拉丁字母的一套电脑编码系统,主要用于显示现代英语和其他西欧语言,其最多只能用 8 位来表示(一个字节),即:2**8 = 256,
所以,ASCII码最多只能表示 256 个符号。因为美国26个英文字母再加上一些字符、数字等,256够够的,但是请思考以下,如果用这个对照表能表示中文吗?答案是可以只要大家认可,8位固定格式当然可以对应一个中文,但是中国有多少字呢?将近十万,但是此对照表一共只能对照256个信息,明显不合适。
由于ASCII码无法将世界上的各种文字和符号全部表示,所以,就需要新出一种可以代表所有字符和符号的编码,即:Unicode
Unicode
Unicode(统一码、万国码、单一码)是一种在计算机上使用的字符编码。Unicode 是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,规定虽有的字符和符号最少由 16 位来表示(2个字节),即:2 **16 = 65536,
注:此处说的的是最少2个字节,可能更多
UTF-8
UTF-8,是对Unicode编码的压缩和优化,他不再使用最少使用2个字节,而是将所有的字符和符号进行分类:ascii码中的内容用1个字节保存、欧洲的字符用2个字节保存,东亚的字符用3个字节保存等等.
所以,python解释器在加载 .py 文件中的代码时,会对内容进行编码(默认ascill),如果是如下代码的话:
#!/usr/bin/env python
print "你好,世界"
默认的ascill则无法显示,需告诉python
应该显著的告诉python解释器,用什么编码来执行源代码,即:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
print "你好,世界"
6. 代码注释
单行注释使用#,只注释当前行的内容
多行注释使用三引号''' '''或""" """,只要在三引号内的所有内容都将注释
7. 变量
#!/usr/bin/env python
# -*- coding: utf-8 -*-
name = "zuowei"
上面的代码声明了一个变量 name 变量name的值为 zuowei
变量的作用是在内存生成 zuowei 的内存地址 ,然后使用一个昵称name 指向zuowei的内存地址,然后使用name则相当于zuowei
变量命名规范
变量名要有描述意义
变量名必须由数字、字母、下划线任意组成
变量名不能过长,不能以数字开头,不能包含中文,不能是抑或包含python关键字
8. 常量
常量即指不变的量,如pai 3.141592653..., 或在程序运行过程中不会改变的量
举例,上面的定义的变量name是常量吗?不是,因为如果我们下面再次设置一下 name = "lp" ,这事name的值已经指向了lp的内存地址,值当然也变了,那它就不是常量,但是数字1,不管变量怎么指向它,或者做其他操作,数字1就是数字1,他不会变,那就是常量。在Python中没有一个专门的语法代表常量,程序员约定俗成用变量名全部大写代表常量
9.数据类型
我们可以很容易的分清数字与字符的区别,但是计算机并不能,计算机虽然很强大,但从某种角度上看又很傻,除非你明确的告诉它,1是数字,“汉”是文字,否则它是分不清1和‘汉’的区别的,因此,在每个编程语言里都会有一个叫数据类型的东西,其实就是对常用的各种数据类型进行了明确的划分,你想让计算机进行数值运算,你就传数字给它,你想让他处理文字,就传字符串类型给他。Python中常用的数据类型有多种,以下列举几个
9.1 int(整型)
在32位机器上,整数的位数为32位,取值范围为-2**31~2**31-1,即-2147483648~2147483647
在64位系统上,整数的位数为64位,取值范围为-2**63~2**63-1,即-9223372036854775808~9223372036854775807
9.2 str(字符串)
在Python中,只要被加了单引或双引号都被认为是字符串,如"zwz"、"22"、"lp"、"True"都为字符串
字符串拼接
>>> mes1 = "zwz"
>>> mes2 = "lp"
>>> mes1 + mes2
'zwzlp'
注: 字符串相加只能字符串 + 字符串
>>> mes1 * 10
'zwzzwzzwzzwzzwzzwzzwzzwzzwzzwz'
注:字符串乘,就是复制自身几次,不能字符串 * 字符串
字符串的索引与切片
索引即下标,就是字符串组成的元素从第一个开始,初始索引为0以此类推
a = 'ABCDEFGHIJK'
print(a[0]) # A
print(a[3]) # D
print(a[5]) # F
print(a[7]) # H
切片就是通过索引(索引:索引:步长)截取字符串的一段,形成新的字符串(原则就是顾头不顾腚)。
a = 'ABCDEFGHIJK'
print(a[0:3]) # ABC
print(a[2:5]) # CDE
print(a[0:]) # ABCDEFGHIJK # 默认到最后
print(a[0:-1]) # ABCDEFGHIJ # -1 是列表中最后一个元素的索引,但是要满足顾头不顾腚的原则,所以取不到K元素
print(a[0:5:2]) # ACE # 加步长
print(a[5:0:-2]) # FDB # 反向加步长
9.3 True,False(布尔值)
布尔类型很简单,就两个值 ,一个True(真),一个False(假), 主要用记逻辑判断
>>>
>>> a = 2
>>> b = 3
>>> a > b
False
>>> a < b
True
9.4 数据类型转换
如果需要转换为str,则str(数据)
如果需要转换为int,则int(数据)
同理其他数据类型也一样
10. 格式化输出
>>> mes = '''
... ------------ info of name -----------
... Name : name
... Age : age
... job : job
... Hobbie : hobbie
... ------------- end -----------------
... '''
如果需要打印上面这一段信息name,age等值是会变的,用字符串拼接的话,则很困难,麻烦
所以可以用格式化输出。
我们只需要把要打印的格式先准备好, 由于里面的一些信息是需要用户输入的,我们没办法预先知道,因此可以先放置个占位符(%),再把字符串里的占位符与外部的变量做个映射关系就ok了。例:
name = input("Please input your name: ")
age = input("Please input your age: ")
job = input("Please input your job: ")
hob = input("Please input your hob: ")
mes = '''
------------ info of %s -----------
Name : %s
Age : %d
job : %s
Hobbie : %s
------------- end -----------------
''' % (name, name, age, job, hob)
print(mes)
报错了,报错信息说%d 必须是一个数字,因为我预定义了此处必须为一个数字,但是我们输入11为什么会报错呢,因为在python3中,它希望能够读取一个合法的python表达式,所以会使用引号括起来,所以默认接收到的都为str类型,我们需要转换age的输入类型
age = int(input("Please input your age: "))
这样就没问题了。
注:如果内容里本就需要有%,则需要改写为%%,才能正常输出%。不然默认会解释为占位符。
11. 基本运算符
计算机可以进行的运算有很多种,不只加减乘除,运算按种类可分为算数运算、比较运算、逻辑运算、赋值运算、成员运算、身份运算、位运算,以下列举算数运算、比较运算、逻辑运算、赋值运算、成员运算。
11.1 算数运算
运算符 | 描述 |
+ | 加 两个对象相加 |
- | 减 两数相减,有可能为一个负数 |
* | 乘 两数相乘,或返回复制了乘数次的字符串 |
/ | 除 x除以y |
% | 取模 返回除法的余数 |
** | 幂 返回x的y次幂 |
// | 取整除 返回商的整数部分 |
11.2 比较运算
运算符 | 描述 |
== | 比较x是否等于y |
!= | 比较x和y是否不相等 |
> | 比较x是否大于y |
< | 比较x是否小于y |
>= | 比较x是否大于等于y |
<= | 比较x是否小于等于y |
11.3 赋值运算
运算符 | 描述 |
= | x = y |
+= | x += y 等同于 x = x + y |
-= | x -= y 等同于 x = x - y |
*= | x *= y 等同于 x = x * y |
/= | x /= y 等同于 x = x / y |
%= | x %= y 等同于 x = x % y |
**= | x **= y 等同于 x = x ** y |
//= | x //= y 等同于 x = x // y |
11.4 逻辑运算
运算符 | 描述 |
and | 如果x为True,y也为True则返回True,否则返回False |
or | 只要x和y有一个为True则为True |
not | 如果x为True返回False,如果为False返回True |
x or y , x为真,值就是x,x为假,值是y
x and y, x为真,值是y,x为假,值是x
在没有()的情况下not 优先级高于 and,and优先级高于or
即优先级关系为( )>not>and>or,同一优先级从左往右计算。如下例题:
not 2 > 1 and 3 < 4 or 4 > 5 and 2 > 1 and 9 > 8 or 7 < 6
11.5 成员运算
运算符 | 描述 |
in | 在指定的序列中找到值返回True,否则返回False |
not in | 在指定的序列中未找到返回值返回Fal,否则返回True |
11.6 运算符优先级
运算符 | 描述 |
---|---|
** | 指数 (最高优先级) |
~ + - | 按位翻转, 一元加号和减号 (最后两个的方法名为 +@ 和 -@) |
* / % // | 乘,除,取模和取整除 |
+ - | 加法减法 |
>> << | 右移,左移运算符 |
& | 位 'AND' |
^ | | 位运算符 |
<= < > >= | 比较运算符 |
<> == != | 等于运算符 |
= %= /= //= -= += *= **= | 赋值运算符 |
is is not | 身份运算符 |
in not in | 成员运算符 |
not and or | 逻辑运算符 |
12. 缩进
所有的代码里,每个条件的下一行都缩进了4个空格,这是为什么呢?这就是Python的一大特色,强制缩进,目的是为了让程序知道,每段代码依赖哪个条件,如果不通过缩进来区分,程序怎么会知道,当你的条件成立后,去执行哪些代码呢?
在其它的语言里,大多通过{}
来确定代码块,比如C,C++,Java,Javascript都是这样,看一个JavaScript代码的例子
var age = 56
if ( age < 50){
console.log("还能折腾")
console.log('可以执行多行代码')
}else{
console.log('太老了')
}
在有{}
来区分代码块的情况下,缩进的作用就只剩下让代码变的整洁了。
Python是门超级简洁的语言,发明者定是觉得用{}
太丑了,所以索性直接不用它,那怎么能区分代码块呢?答案就是强制缩进。
Python的缩进有以下几个原则:
- 顶级代码必须顶行写,即如果一行代码本身不依赖于任何条件,那它必须不能进行任何缩进
- 同一级别的代码,缩进必须一致
- 官方建议缩进用4个空格,当然你也可以用2个,如果你想被人笑话的话。
13. 流程控制--if
假如把写程序比做走路,那我们到现在为止,一直走的都是直路,还没遇到过分叉口,想象现实中,你遇到了分叉口,然后你决定往哪拐必然是有所动机的。你要判断那条岔路是你真正要走的路,如果我们想让程序也能处理这样的判断怎么办? 很简单,只需要在程序里预设一些条件判断语句,满足哪个条件,就走哪条岔路。这个过程就叫流程控制
单分支
if 条件:
满足条件后要执行的代码
抑或
if 条件:
满足条件后要执行的代码
else:
不满足条件后要执行的代码
多分支
if 条件:
满足条件执行代码
elif 条件:
上面的条件不满足就走这个
elif 条件:
上面的条件不满足就走这个
elif 条件:
上面的条件不满足就走这个
else:
上面所有的条件不满足就走这段
例子:
score = int(input("输入分数: "))
if score > 100:
print("最高分才100...")
elif score >= 90:
print("A")
elif score >= 80:
print("B")
elif score >= 60:
print("C")
elif score >= 40:
print("D")
else:
print("太笨了...")
这里有个问题,就是当我们输入95的时候 ,它打印的结果是A,但是95 明明也大于第二个条件elif score >=80:
, 为什么不打印B呢?这是因为代码是从上到下依次判断,只要满足一个,就不会再往下走了!
14.流程控制--while
如果在循环的过程中,因为某些原因,你不想继续循环了,怎么把它中止掉呢?这就用到break 或 continue 语句
- break用于完全结束一个循环,跳出循环体执行循环后面的语句
- continue和break有点类似,区别在于continue只是终止本次循环,接着还执行后面的循环,break则完全终止循环
基本结构:
while 条件:
执行的代码块
抑或:
while 条件:
执行的代码块
else:
print("循环正常执行完啦")
while 后面的else 作用是指,当while 循环正常执行完,中间没有被break 中止的话,就会执行else后面的语句
如果执行过程中被break了,就不会执行else的语句。
注:千万注意while循环的这个条件,这个条件必须有False的时候,不然会死循环!
15. for、enumerate,range
用户按照顺序循环可迭代对象的内容。
msg = 'zwz love lp'
for item in msg:
print(item)
li = ['zs','ls','xm','zw','lp']
for i in li:
print(i)
dic = {'name':'zw','age':18,'sex':'man'}
for k,v in dic.items():
print(k,v)
enumerate:枚举,对于一个可迭代的(iterable)/可遍历的对象(如列表、字符串),enumerate将其组成一个索引序列,利用它可以同时获得索引和值。
li = ['zhangsan','lisi','angel','zw','lp']
for index, name in enumerate(li, 1):
print(index, name)
for index, name in enumerate(li, 100): # 起始位置默认是0,可更改
print(index, name)
range:指定范围,生成指定数字。
for i in range(1,10):
print(i)
for i in range(1,10,2): # 步长
print(i)
for i in range(10,1,-2): # 反向步长
print(i)