零、预备知识
0.1 字符编码
计算机只能处理数字,所以为文本需要转化为数字才能被计算机处理,计算机里八个比特(bit)作为一个字节(byte),这是数据的存储基础单位。计算机为了处理文本,有以下三种编码方式:
- ASCII码:只有大小写英文字母,数字,一些符号共127个;1个字节,
- Unicode码:所有语言都统一在一套编码里;一般2个字节,生僻字4个字节;在ASCII码前补0就行
- UTF-8编码:根据不同的数字大小编码成1-6个字节;常用的英文字母1个字节,汉字3个字节,生僻的字符4-6个字节;ASCII编码实际上可以被看成是UTF-8编码的一部分
计算机内存统一使用Unicode编码,保存在硬盘(例如文件保存)里或网络传输时转换为UTF-8编码
一、简介
- 程序运行都是通过机器指令执行的,编程语言其实相当于机器指令和自然语言间的一个桥梁,编程语言在运行时都将会翻译为计算机可以识别的机器指令。
- python是一门高级的语言,其代码行数少,因而运行时间也长。完成同样的一个功能,c语言可能需要1000行,Java100行,python20行。
- python一般用于实现应用程序,如算法,网站后台,在线游戏后台,c语言一般用于底层的接近硬件的开发如操作系统,java一般用于网站开发和Android,swift/objective-c主要用于iPhone开发
- 解释型语言:python是解释型语言,在运行时逐行翻译为机器码;c语言则是编译型语言,它在运行前编译为机器码。
- 动态数据类型:python数据类型为动态,不同类型变量可以相互赋值,而类似于java,c是静态类型,声明变量时需声明数据类型,数据类型不同相互赋值则会报错
1.1 优点:
- 代码量少
- 有丰富的基本库和第三方库,基本代码库包含网络,GUI,数据库,文件,文本等方面
1.2 缺点:
- 程序运行时间长
- 代码不能加密。分享代码只能通过源代码,不像c语言可以分享编译后的机器码
1.3 适用方面:
- 日常小工具
- 网络应用,如网络后台,在线游戏
- 封装其他语言完成的程序
二、安装python
- python是跨平台的,在windows上编写的代码直接搬到mac/linux上也可以运行
- 安装python的时候你将会得到一个python解释器,包括一个pyhton命令行交互运行环境和一个集成开发环境
2.1 安装步骤:
- 下载安装:从Python官网下载pyhton的exe安装文件,一路下一步安装后即可(注意将python.exe路径加入path环境变量里,不然Windows可能没办法找到)
- 进入命令行交互环境:在windows系统下打开cmd命令行提示符窗口,提示符类似
c:>
- 进入python交互环境:在命令行提示符窗口里输入
python
,出现提示符>>>
,这就表明已经进入python交互运行环境,然后就可以输入python代码,回车则执行 - 退出python交互环境:输入
exit()
并回车,则可以退出
2.2 python解释器:
我们编写python代码时会得到一个后缀为.py的文本,我们需要一个Python解释器来解释,Python解释器包含很多版本
- CPython: python的官方解释器,用c语言开发出来的,在命令行交互窗口里输入python则启动CPython解释器,提示符是
>>>
- IPython: 基于CPython的解释器,在CPython的解释方式上有所增强,执行程序得到结果和CPython一样,提示符是
In[符号]
- pypy: 采用JIT技术,对Python代码进行动态编译(注意不是解释),执行程序结果可能和CPython不同
- Jython:运行在Java平台上的解释器,可以把Python代码编译成为Java字节码
- ItonPython:运行在微软.Net平台上的解释器,可以直接把Python代码编译成.Net的字节码
三、第一个python程序
命令行模式和python交互模式:
- 命令行模式: 用
cd 路径
命令行将路径转到需要执行的Python文件的目录下,然后用命令行python xx.py
执行文件,相当于启动了Python解释器,一次性执行Python代码 - Python交互模式: 直接输入
Python
代码则可以输出代码执行结果,相对于启动Python解释器,输入一行代码就执行一行,一般用作调试Python代码,具体例如下
>>>100+200
300
>>>print("hello world!")
hello world!
在打代码时可以一边在文本编辑器里编辑,一边粘贴到Python交互环境里进行调试。
四、Python基础
4.1 输出print()
- 输出单个字符串:
print("hello world!")
- 输出多个字符串:
print("hello,world")
多个字符串用逗号隔开,输出时逗号变成空格 - 输出运算式:
print(200+100)
- 输出字符串和运算式:
print("100+200=",100+200)
4.2 输入input()
- 输入字符串存在变量里:
s=input()
,此时name是str类型,要变成int类型需要函数int(),news=int(s)
- 输入字符串前显示提示信息:
name=input("please enter your name")
4.3 基础
- 注释:
#注释
- 代码块:Python代码每一行是一个语句(结尾不用;),语句以冒号:结尾时缩进的代码为代码块
- 缩进: 缩进为四个空格
- Python严格大小写
#输出最大值
a=100
b=200
if(a>b):
print(a)
else:
print(b)
4.4 数据类型
整数:Python可以处理任意大小的整数,包括负整数,八进制
0
开头,十六进制0X
开头,如:1,3,04,0xff00,-394
,整数运算永远是精确的,大小没有限制range(n)
函数,生成一个从0到n-1的整数序列>>>list(range(5)) [0, 1, 2, 3, 4]
- 浮点数:浮点数就是小数,很大的小数用科学计数法,如:
2.23,-3.22,1.23e8
,浮点运算可能因为四舍五入产生误差,大小没有限制,但是超过某个范围则为inf(无限大) 字符串:用” “或’ ‘包裹起来,如果需要字符’ ‘则用” “包裹,如果同时需要’ 和”则需要转义
\' ' \" " \\ \ \n 换行 \t 制表符 r"" 默认不转义,转移符将按原字符表示 ''' ''' 输入的换行可以保留
字符串常用函数:ord(‘字符’)获得字符编码的十进制表示;chr(‘编码’)获得编码对应函数;len(“字符串”)计算字符串的字符数,len(b’byte’)计算byte字节数
>>>ord('A') 65 >>> ord('中') 20013 >>> chr(66) 'B' >>> chr(25991) '文' #知道字符十六进制表示可直接用'\xxx\xxx'写str >>> '\u4e2d\u6587' '中文' >>> len('中文') 2 >>> len('中文'.encode('utf-8')) 6 b = a.replace('a', 'A') //b是将a中a替换为A的字符串Abc,a仍旧是原字符串abc
字符串格式化:,可以用占位符或
format()
函数进行格式化,%d
整数(%2d表示长度为2,%02d表示长度为2,不足补零),%f
浮点数(%.2f表示保留两位小数),%s
字符串(可以将任何类型数据转换为字符串),%x
十六进制整,format用{0}{1}
占位>>>'Hi, %s, you have $%d.' % ('Michael', 1000000) 'Hi, Michael, you have $1000000.' >>> 'Hello, {0}, 成绩提升了 {1:.1f}%'.format('小明', 17.125) 'Hello, 小明, 成绩提升了 17.1%'
字符串编码:
python中:str类型;Unicode编码;占多个字节;‘’
;用encode(编码方式名)
编码
磁盘和网络中:byte类型;ASCII编码和utf-8编码;占一个字节;b‘’
;用decode(编码方式名)
解码
#编码
>>>'ABC'.encode('ascii')
b'ABC'
>>> '中文'.encode('utf-8')
b'\xe4\xb8\xad\xe6\x96\x87'
#解码
>>> b'ABC'.decode('ascii')
'ABC'
>>> b'\xe4\xb8\xad\xe6\x96\x87'.decode('utf-8')
'中文'
- 布尔值:
Flase
和True
,运算符是and or not
非零数值,非空字符串,非空list都是true - 空置:None
字典
查找插入速度快,不会随元素增加变化,需要大量内存,内存浪费多
dict类型:使用健-值(key-value)存储,可以通过key采用hash算法直接计算出value的存放位置,所有key只能是不可变数据,例如str,int,不能是list声明:`d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}` 取值:d['key'] 判断key是否存在:`'key' in data`或者data.get('key') 删除:`data.pop('key')` 赋值:`data['key']=newdata`
set类型:一组无序的不重复的key集合,没有vaule,需要一个list作为输入集合,key也只能是不可变对象
声明:s=set([1,2,3,3]) //重复元素自动变为一个,s为{1,2,3} 添加:s.add(4) 删除:s.remove(4) 交集并集:s1&s2 s1|s2 //和数学的交集并集一样
列表
查找插入速度随元素增加变慢,需要少量内存,内存浪费少
list类型:相当于数组,按顺序查找
声明:classmates = ['Michael', 'Bob', 'Tracy']
,其中元素类型可不同,用[]声明
索引:从0到len(classmates-1)或-1,同理倒数第二个索引为-2以此类推
函数:append(),pop(),insert().len(),list()classmates.append('Adam') //追加 classmates.insert(索引位置, 'Jack') //插入指定位置 classmates.pop() //删除末尾 classmates.pop(索引位置) //删除指定位置 classmates[1] = 'Sarah' //指定位置赋值 len(s) //list元素个数 classmate.sort() //根据内容字典排序 list() //强制转换为list
tuple类型:和list相似,但一旦初始化其元素就不能修改,元素自身指向如list可修改,获取元素方式和list一样
声明:classmates = ('Michael', 'Bob', 'Tracy')
,只有一个元素需要加,不然不会认作tuple类型t = (1,)
,用()声明
- 自定义
4.5 变量
- 变量名:数字,大小字母,_,不能数字开头
- 同一变量可以反复赋值,无论赋值类型
- 除法/得到数据均为浮点数,//得到数据均去掉小数部分,为整数,%取两个整数的余数
4.6 常量
- python没有固定常量,默认用大写的变量名表示常量
五、语句
5.1条件语句
注意if,else if,elif
后面是:靠缩进区别代码块,逻辑运算符用and
,or
,not
if <条件判断1>:
<执行1>
elif <条件判断2>:
<执行2>
elif <条件判断3>:
<执行3>
else:
<执行4>
5.2 循环语句for x in data:
把list和tuple类型的data中的每个元素依次代入x
names = ['Michael', 'Bob', 'Tracy']
for name in names:
print(name)
for x in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]:
print(x)
while:
条件满足,就不断循环,条件不满足时退出循环
while n > 0:
sum = sum + n
break:
可以在循环过程中直接退出循环continue:
直接开始下一轮循环
六、函数
函数名是指向一个函数对象的引用,把函数名赋给一个变量,相当于给这个函数起了一个“别名”
6.1 调用函数
调用函数需要函数的名称和参数,可以参考python官网:http://docs.python.org/3/libr…,如果输入的参数数目或类型不对会报TypeError的错
TypeError: abs() takes exactly one argument (2 given)
TypeError: bad operand type for abs(): 'str'
6.2 数据类型转换
python常用函数还包括数据类型转换函数,如int()函数可以把其他数据类型转换为整数
6.3 函数定义
函数定义由def,函数名(参数),return表示,如果没有return语句,函数执行完毕后返回None。return None可以简写为return
def 函数名(参数):
if x >= 0:
return x
else:
return -x
在python交互环境里定义,会出现…,定义完毕后输入两次回车出现提示符,即可执行
如果函数定义在文件new.py里,则可以用命令行python new import 函数名
导入函数,然后再执行
空函数:用pass占位,也可用于if代码块里
def nop():
pass
参数检查:python可以检查内置函数参数个数和类型,自定义函数只能检查个数,类型需要用isinstace()
自定义检查
def my_abs(x):
if not isinstance(x, (int, float)):
raise TypeError('bad operand type')
返回多个参数:函数返回多个参数return a,b
,实际是返回一个tuple类型数据,如果函数赋给多个变量c,d = new(1,2)
,则是将函数返回的tuple类型数据依次赋给c,d;如果函数赋给一个变量e = new(1,2)
,则e即为这个tuple类型变量
def new(a,b):
a=0
b=1
return a,b
>>>c,d = new(1,2) //c=1,d=2
>>>e = new(1,2) //e[0]=1,e[1]=2
6.4 函数参数
默认参数:power(x,n=2)
默认参数n取值为2,当调用函数书写为power(1)
时,相当于调用power(5,2)。注:必选参数在前,可选参数在后,默认值不是最后一个需指定参数名
def enroll(name, gender, age=6, city='Beijing'):
...
enroll('Sarah', 'F')
enroll('Bob', 'M', 7)
enroll('Adam', 'M', city='Tianjin')
注:默认参数最好指向不变对象,如str,int,None
可变参数:传入参数个数可变,参数用*numbers表示,此刻参数numbers接收到一个tuple类型数据
def calc(*numbers):
sum = 0
for n in numbers:
sum = sum + n * n
return sum
calc(1,2,3,4)
#若已有一个tuple或list,则可以用`clac(*nums)`调用
nums = [1,2,3]
clac(*nums)
关键字参数:传入任意个参数person('Bob', 35, city='Beijing',job='Engineer')
,这些关键字自动组装为一个dict,person(name,age,**kw)
,此刻dict为{'gender': 'M', 'job': 'Engineer'}
def person(name, age, **kw):
print('name:', name, 'age:', age, 'other:', kw)
person('Adam', 45, gender='M', job='Engineer')
#若已有一个dict,可用person(**extra)调用
extra = {'city': 'Beijing', 'job': 'Engineer'}
person('Jack', 24, **extra)
6.5 递归函数
def fact(n):
if n==1:
return 1
else:
return n*fact(n-1)
栈溢出:计算机里函数调用是通过栈完成,调用一个函数栈加一个栈帧,调用完成减一个栈帧,如果递归太多次会导致栈溢出
尾递归:为了防止栈溢出,就可以采取尾递归方式,即每次函数返回时调用函数自身,这样无论递归多少次都只占用一个栈帧
def fact2(n):
return fact2_iter(n,1)
def fact2_iter(n,product):
if n==1:
return product
else:
return fact2_iter(n-1,product*n)
理论上只要解释优化后尾递归不会出现栈溢出,但是目前大多数解释器包括python解释器并没有进行解释器优化。