python基础全笔记
以下为思维导图xmind转换的文本文件
Python编程基础
1、导论入门
Python简介
诞生
1989年圣诞节,吉多·范罗苏姆 (Guido van Rossum)为了打发圣诞节假期创造了Python
1991年,Python第一个公开版本正式发布
命名
Python是Guido以喜剧团体Monty Python(巨蟒小组)的名字命名的
作者
吉多·范罗苏姆 (Guido van Rossum)是荷兰人
1982年,Guido从阿姆斯特丹大学(University of Amsterdam)获得了数学和计算机硕士学位,并在荷兰的CWI
(Centrum voor Wiskunde en Informatica,国家数学和计算机科学研究院)工作
1995年移居美国,2005年加入Google公司,目前在Dropbox公司
为什么选择Python?
代码风格
简洁
优雅
高效
人生苦短,我用Python
注:Python将许多机器硬件层面上的细节隐藏,交给底层编译器处理,并凸显逻辑层面的编程思考;
程序员将精力和时间更多用于思考程序的逻辑和高级抽象,而不是具体的实现细节。
开发效率
有很多第三方库
完善的基础代码库
高级重用机制
面向对象程序设计OOP
可移植跨平台
跨平台支持WIN、Linux/Unix、MAC主流操作系统
使用范围
使用者广泛
TIOBE排名靠前
前5
前4
前3
知名项目丰富
Youtube
Instagram
OpenStack
Google
NASA
Cisco
豆瓣
知乎
最适合初学者的编程语言!
国外很多高校开始用python作为编程第一教学语言~~~
我们学Python可以做什么?
作为网络/安全工程师,为什么学Python?
批量部署
安全渗透
安全研发
SDN软件定义网络
作为运维工程师,为什么学Python?
自动化运维
云计算运维
作为软件工程师,为什么学Python?
文本处理
Web开发
图形开发
网络爬虫
游戏开发
科学计算
全栈语言
有哪些经典的Python教材?
书籍
《A Byte of Python》
Swaroop C H
简明Python教程
《Python编程入门》
Toby Donaldson
《Python学习手册》
Mark Lutz
《Python核心编程》
Wesley J. Chun
第二版
理论
第三版
应用
《笨方法学Python》
Zed Shaw
网站
www.python.org
手册
https://docs.python.org/2/
https://docs.python.org/3/
2、环境安装
理解程序运行
语言对比
语言概览
低级语言
机器型语言
二进制代码0和1
CPU内部工作指令
硬件才能读懂
汇编语言
符号语言
高级语言
编译型语言
C
C++
解释型语言
Python
Perl
Ruby
Java属于解释型和编译型之间的一种语言
运行流程
机器语言
汇编语言
编译语言
解释语言
术语解读
source code
python源代码,即程序员最开始编写的代码
print 'hello, world'
Python源代码一般以.py格式保存
complier
编译器,将源代码编译成字节码
bytecode
源代码被编译之后的代码称为字节码
字节码一般是.pyc格式
再次运行程序则不再需要编译
字节码主要是为了实现软硬环境无关,实现可移植/跨平台
不同系统上字节码是一样的,但是根据平台不同,编译所生成的机器码有区别
字节码是源代码和机器码的中间形态
interpreter
PVM(Python Virtual Machine)
解释器/虚拟机将字节码转译为可以直接执行的机器码
native code
机器码即虚拟机/解释器能够读懂的语言
processor
CPU/处理器最终读取机器码执行程序
特点总结
机器语言是二进制执行代码,无需“翻译”过程,CPU处理器可以直接读取,其他语言最终都需要统一编译为机器语言执行
汇编语言需要一次编译过程,硬件相关无法移植,抽象程度低/可读性差,执行效率很高/开发效率较低
编译语言需要一次编译过程,硬件无关可移植,抽象程度高/可读性强,执行效率较高/开发效率较高
解释语言需要两次“翻译”,硬件无关可移植,抽象程度超高/可读性最强,执行效率较低/开发效率最高
安装开发环境
原生开发环境
Windows系统
官网下载
www.python.org
版本说明
2.7
3.5
软件安装
3.5
2.7
环境变量
我的电脑->属性->环境变量->Path->;c:\python27
WIN+R -> cmd -> DOS
输入python,查看是否进入>>>交互模式
程序执行
交互模式
选择Python安装包自带IDE工具=>IDLE
hello,world!
脚本模式
#hello.py
print 'hello, world!'
python hello.py
交互模式方便实验验证,适合小程序,即使生效不存储;
脚本模式是主要的编程模式,适合编写大中程序,能存储。
Mac/Linux/Unix系统
系统自带
输入python即可执行
代码编辑器
Sublime Text
跨平台
Windows
Mac
Unix/Linux
Notepad ++
Windows平台
Vim
Unix/Linux平台
集成开发环境IDE
PyCharm
专业的面向Python编程的IDE工具
代码调试
代码高亮
代码跳转
智能提示
自动完成
单位测试
项目管理
Django
IronPython
Google App Engine
由软件公司JetBrains开发,商业化IDE软件
社区版
专业版
Eclipse+Pydev
著名的开源集成开发平台(由IBM开发后面开源),通过PDE插件开发环境的拓展,
可以用于开发Java、C、C++、Python等
编写第一个程序
方法一
代码编辑器 + Python执行
方法二
集成开发环境IDE
PyCharm
安装python27或者35
设置环境变量
安装PyCharm
创建Python项目
创建Python文本
测试运行
交互模式
Eclipse+Pydev
安装Java虚拟机 JRE/JDK
设置环境变量
安装python27或者35
设置环境变量
安装Eclipse
安装Pydev并关联
在线安装
点击Eclipse菜单“帮助-安装新软件”
添加安装
Pydev
http://pydev.org/updates
关联Eclipse
Window-> Preferences -> PyDev
Intepreter – Python:按 “Auto-Config”, Eclipse必须发现Python的安装目录。
点击Python并Apply
离线安装
Pydev官网下载安装包
将Pydev安装包内的plugins和features文件夹内的内容复制到eclipse的解压目录的相应文件夹中
打开Eclipse中Window菜单,选择Preference, 找到左侧边栏的Pydev, 点击Interpreter-Python
点击new,找到Python安装路径应用即可
关联Python解释器
创建Python项目
创建Python文本
测试运行
3、对象类型
对象
对象的定义
编程是什么?
编程的本质便是“do things”
编程就是“一动一静”,解决事情、处理问题。
动
解决
处理
执行
静
事情
问题
东西
怎么编程?
围绕“do"解决、处理、流程为依据来进行编程,称为“面向过程编程”
POP(procedure-oriented programming)
围绕“things"东西、事情、数据为依据来进行编程,称为“面向对象编程”
OOP(object-oriented programming)
举例
我要好好学Python!
面向过程
收集教程
教材
文档
视频
学习语法
项目练手
完成学习
面向对象
对象1
我(人)
对象2
Python(物)
对象3
学习
视频
教材
文档
从学习的流程入手
从学习这件事情的对象分解开始
什么是对象?
Python是一种“面向对象编程”的语言,所以Python语言中,一切皆对象!
Python语言中,所有能够被处理的、被解决的“东西”,都称之为对象(Object)
对象有各自特性和行为,例如猴子(能上树),树懒(爱睡觉)……
对象的组成
对象的特性
对象是什么?(what)
对象的数据、对象的状态,是一种静态信息。
值value:对象表示的数据项
身份id:唯一性身份标志,是该对象的内存地址,可用内建函数id()获得
类型tpye:对象的类型决定了该对象可以保存什么类型的值,可进行什么样的操作,以及遵循什么样的规则,可以type()获得
对象的行为
对象能做什么?(how)
对象的操作、功能、方法等,是一种动态信息。
我们将对象能做的,统称为 “方法/属性/操作”
方法method
通过dir( )获得
函数function
操作operation
对象的举例
例子1:人/程序员/小明
特征
名字
小明
身高
170cm
体重
60kg
年龄
18岁
行为
吃饭
学习
工作
敲代码
例如2:物/书籍/《Python秘籍》
特征
书名
类别
页数
价格
行为
存储知识
激发灵感
对象的类型
基础对象类型
数字
字符串
列表
元组
字典
集合
进阶对象类型
文件
函数
模块
类
其他叫法
核心数据结构
内置对象类型
内置数据类型
数字
数字是什么?
整数
定义
整数便是我们平常用的最多的数字,如1、-1、0
分类
以正负区分
正整数
1
负整数
-1
以进制区分
十进制
1
20
100
十六进制
0x2f
以0x开头
八进制
012
以0开头
python2.7
只用数字0放在前面
0o12
以0o
python3.5
除了数字0,必须加入字母o的大写或者小写
范围
无穷大
实际上取决于内存大小
2 ** 100
2的100次方
浮点数
定义
浮点数即我们平常使用的小数,如10.12、7.88
举例
1.5
-1.2233
10.2e99
10.2 * 10^99
科学记数法
31.5e-12
31.5 * 10^-12
科学记数法
范围
占8个字节/64比特
遵循IEEE754规范
52bit表示底,11bit表示指数,另外1个bit表示符号
换算之后范围大概是正负10的308.25次方
浮点数除了范围限制,计算中也会出现误差
不建议使用做精确的计算
拓展
为什么浮点数计算的时候是不精确的?
①计算机存储数据的时候是需要转换成二进制的
②很多小数转换为二进制是无穷大的,但机器存储是有限的(64bit),所以需要截断处理
0.1(十进制) = 0.0001100110011001(二进制)
超出计算精度,结果保留十六位小数
③浮点数运算不精确的例子
错误
>>> 0.1 + 0.1 + 0.1 - 0.3
5.551115123125783e-17
溢出
>>> 500.0 ** 10000
浮点数会溢出
Traceback (most recent call last):
File “”, line 1, in
OverflowError: (34, ‘Result too large’)
>>> 500 ** 10000
整数不会溢出
50123727492064520092975559337……
复数
定义
复数涉及到-1的平方根的数字,1j表示-1的平方根
复数由实部和虚部组成,如1+2j
举例
1.11 + 2j
2.33 - 8.5j
布尔型
定义
布尔型(bool)本质是整数类型的一种,只有True和False两个值
1和0
可以用于逻辑判断,多用于判断语句中
举例
>>> 1 > 2
False
>>> 10 < 20
True
其他
分数
空值
常量
如何操作数字?
运算符
算术运算符
加法
+
1 + 1
减法
-
10 - 5
乘法
*
2 * 5
除法
/
20 / 4
整除
//
25 // 3
取余
%
25 % 3
乘方
**
>>> 3**2
9
>>> -3 ** 2
-9
>>> 4.0 ** -1.0
0.25
运算优先级
优先级高的优先计算
1 + 1 * 2
优先级相同按书写顺序计算
1 + 1 - 2
需要改变计算优先级采用括号( )
( 1 + 1 ) * 2
比较运算符
==
等于
>>> 10.1 == 10.1
True
>=
大于等于
>>> -619 >= 855
False
<=
小于等于
>>> 0. <= -10.1
False
<
小于
>>> 2 < 5
True
>>> 2 < 5 < 9
True
>
大于
>>> -619 > 877
False
>>> 78 > 69 == 69
True
!=
不等于
>>> 100 != 90
True
布尔运算符
与运算
and
>>> True and True
True
>>> True and False
False
>>> False and False
False
或运算
or
>>> True or True
True
>>> True or False
True
>>> False or False
False
非运算
not
>>> not True
False
>>> not False
True
内建函数
数值计算函数
abs( )
功能
返回给定参数的绝对值
举例
>>> abs(-1)
1
>>> abs(1.2-2.1j)
2.4186773244895647
>>> abs(0.23 - 0.78)
0.55
pow( )
功能
用于进行指数运算
举例
>>> pow(2, 5)
32
>>> pow(5, 2)
25
>>> pow(1+1j, 3)
(-2+2j)
round( )
功能
用于对浮点数进行四舍五入运算,返回与第一个参数最接近的整数
有可选的小数位位数参数,告诉round函数将结果精确到小数点后指定位数
举例
>>> round(3)
3.0
>>> round(3.45)
3.0
>>> round(3.4999)
3.0
>>> round(3.4999, 1)
3.5
>>> round(8.8)
9.0
>>> round(8.4)
8.0
其他
>>> import math
>>> for eachNum in range(10):
… print round(math.pi, eachNum)
…
3.0
3.1
3.14
3.142
3.1416
3.14159
3.141593
3.1415927
3.14159265
3.141592654
对比
int( ) round( ) math.floor( )
{ 函数 int()直接截去小数部分。(返回值为整数)
{ 函数 floor()得到最接近原数但小于原数的整数。(返回值为浮点数)
{ 函数 round()得到最接近原数的整数。(返回值为浮点数)
divmod( )
功能
把除法和取余运算结合,返回一个包含商和余数的元祖
举例
>>> divmod(10, 3)
(3, 1)
>>> divmod(3, 10)
(0, 3)
>>> divmod(10,2.5)
(4.0, 0.0)
coerce( )
功能
将两个数值转换为一个类型,然后创建包含两个数值的元祖
举例
>>> coerce(10, 0.1)
(10.0, 0.1)
>>> coerce(1.3, 134L)
(1.3, 134.0)
>>> coerce(1j, 134L)
(1j, (134+0j))
类型转换函数
int( )
功能
用于将其他数字类型转换为整数
截去小数部分,并且返回整数
举例
>>> int(1.1)
1
>>> int(99.11)
99
complex( )
功能
用于将其他数字类型转换为复数
举例
>>> complex(1)
(1+0j)
float( )
功能
用于将其他数字类型转换为浮点数
举例
>>> float(1)
1.0
long( )
功能
用于将其他数字类型转换为长整数
举例
>>> long(1)
1L
bool( )
功能
用于转换一个参数为布尔值
类型值转换bool值时除了’’、""、0、()、[]、{}、None、0.0、0L、0.0+0.0j、False为False,其他都为True
举例
>>> bool(0)
False
>>> bool(False)
False
>>> bool(’’)
False
>>> bool([])
False
>>> bool(None)
False
>>> bool(-1)
True
>>> bool(1)
True
>>> bool(True)
True
进制转换函数
hex( )
功能
用于接收一个整数对象,然后返回对应十六进制的字符串对象
举例
>>> hex(255)
‘0xff’
>>> hex(2309999231)
‘0x89afca7f’
oct( )
功能
用于接收一个整数对象,然后返回对应八进制的字符串对象
举例
>>> oct(255)
‘0377’
>>> oct(2399919191)
‘021702756127’
bin( )
功能
用于接收一个整数对象,然后返回对应二进制的字符串对象
举例
>>> bin(1)
‘0b1’
>>> bin(2)
‘0b10’
>>> bin(3)
‘0b11’
ASCII转换函数
ord( )
功能
接收一个字符,返回其对应的整数值
范围从0到255
举例
>>> ord(‘a’)
97
>>> ord(‘A’)
65
chr( )
功能
接收一个整数值,返回一个字符串
范围从0到255
举例
>>> chr(97)
‘a’
内置模块
math
功能
高级数学计算模块,包含很多预先编写好的函数代码
cos(x)
x的余弦
sin(x)
x的正弦
tan(x)
x的正切
sqrt(x)
x的平方根
……
举例
>>> import math
>>> math.sqrt(4)
>>> math.sqrt(4)
没有导入math模块时
Traceback (most recent call last):
File “”, line 1, in
NameError: name ‘math’ is not defined
2.0
>>> math.sin(5)
-0.9589242746631385
random
功能
随机数学模块
该模块包含多个伪随机数发生器,以当前时间戳为随机数种子
举例
randrange( )
随机返回(最小值, 最大值)结果的一项整数
>>> import random
>>> random.randrange(1, 10)
8
>>> random.randrange(1, 10)
9
>>> random.randrange(1, 10)
2
uniform( )
返回二者之间的一个浮点数
>>> import random
>>> random.uniform(1, 10)
3.2570408274280154
>>>
>>> random.uniform(1, 10)
2.072617258882051
>>> random.uniform(1, 10)
1.630710796726217
choice( )
随机返回给定序列的一个元素
>>> import random
>>> random.choice([1, 2, 3])
2
>>> random.choice([1, 2, 3])
3
NumPy
变量
变量是什么?
定义
变量是一种对象引用,好比一个‘链接’,指向任何数据/对象类型
引用
指针
链接
赋值
功能
可以让代码更加容易阅读
可以方便调用对象类型
可以写出更加复杂的代码
>>> a = 1
>>> b = 2
>>> x = a + b
>>> print x
3
原理
>>> a = 123
>>> id(a)
通过id( )查看内存空间地址
140249502136112
特征
变量在第一次赋值时被创建(内存中)
第一次赋值时,Python解释器会在内存中创建对象,然后再创建变量指向这个对象
再次使用该变量时,则内存无需再创建该变量
变量像对象一样不需要一开始进行类型声明
变量本身类型不固定的语言,我们称之为动态语言,与之对应的是静态语言;
静态语言在定义变量时必须指定变量类型,如果赋值的时候类型不匹配,就会报错。
变量在表达式中使用之前必须先赋值
a = ‘pinginglab’
print a
变量在表达式中使用将被替换为它们所指向的值
a = 1
a + 2
变量如果没有指向一个对象,则会被垃圾回收
如何操作变量?
变量赋值
变量赋值说明
赋值语句
var = value
var 变量
variable
= 赋值运算符
value 对象
命名规则
变量名的长度不受限制,但其中的字符必须是字母、数字或下划线(_),而不能使用空格、连字符、标点符号、引号或其他字符。
不能是‘a’或!a
变量名的第一个字符不能是数字,而必须是字母或下划线。
不能是123,可以是a123
变量名是大小写区分的,a和A的变量是不同的。
不能将Python关键字用作变量名。
不能是if/else/while/def等关键词
变量赋值(数字)
a = 123
变量赋值(布尔值)
a = True
变量赋值(字符串)
a = 'hello, world'
变量赋值(列表)
a = [1, 2, 3]
其他例子
例子1(多重赋值)
>>> a, b, c = 1, 2, 3
>>> print a
1
>>> print b
2
>>> print c
3
例子2(交叉赋值)
a = 123
b = a
a = 'xyz'
print b
图解
交换两个变量的值
a=1
b=2
a,b=b,a
附加案例
>>> a = 300
>>> b = 100 + 200
>>> id(a)
140268284424512
>>> id(b)
140268284427576
>>> c = 300
>>> d = c
>>> id©
140268284427744
>>> id(d)
140268284427744
>>> e = 400
>>> f = 400
>>> id(e)
140268284424680
>>> id(f)
140268284424968
序列
字符串
字符串是什么?
定义
字符串(String)即一组有序的字符组合,由字母、数字、符号等信息组成。
功能
用于存储和表现基于文本的信息
文档
txt
word
网页
html
语法
变量 = 字符串
s = 'hello, world'
单引号
双引号
三引号
主要用于多行字符串/文本说明
>>> s = """
... hello, world!
... Welcome to PINGINGLAB!
... """
单双引号混用可以使得字符串本身包含“或‘
>>> "it's python"
"it's python"
>>> 'Hi,This is "PINGINGLAB"'
'Hi,This is "PINGINGLAB"'
特征
有序
字符串中的元素按照顺序从左到右存储
不可变
概述
Python对象类型根据对象内容本身是否可修改,分为可变对象和不可变对象两类
数字、字符串、元组是不可变的;列表、字典是可变的
举例
字符串不可变举例
>>> A = '123'
>>> A[0] = '4'
Traceback (most recent call last):
File "<input>", line 1, in <module>
TypeError: 'str' object does not support item assignment
列表可变举例
>>> A = [1, 2, 3]
>>> A[0] = 4
>>> A
[4, 2, 3]
如何操作字符串?
操作符
索引操作符
[]
操作语法
字符串[索引值x]
访问索引为x的字符
正向索引
s[1]
>>> s = 'hello'
>>> s[1]
'e'
反向索引
s[-1]
>>> s = 'hello'
>>> s[-1]
'o'
切片操作符
[:]
操作语法
字符串[索引值x:索引值y]
访问索引从x到y的字符,包括x不包括y
正向切片
s[0:2]
>>> s = 'hello'
>>> s[0:2]
'he'
反向切片
s[-3:-1]
>>> s[-3:-1]
'll'
默认切片
s[1:]
>>> s[1:]
'ello'
s[:-3]
>>> s[:-3]
'he'
扩展切片[start:end:step]
反向输出字符串字符
a[::-1]
连接操作符
+
s1 + s2
>>> s1 = 'hello, '
>>> s2 = 'world!'
>>> s3 = s1 + s2
>>> s3
'hello, world!'
重复操作符
*
s * n
>>> s1 = 'hello'
>>> s1 * 10
'hellohellohellohellohellohellohellohellohellohello'
成员操作符
in
>>> s1 = 'hello'
>>> 'h' in s1
True
>>> 'he' in s1
True
not in
>>> 'he' not in s1
False
内置函数
判断函数
s.isalnum()
功能
判断字符串s是否只包含字母和数字,如果是返回True,否则返回False
举例
>>> s1 = 'abc'
>>> s2 = '123'
>>> s3 = 'a1b2c3'
>>> s1.isalnum()
True
>>> s2.isalnum()
True
>>> s3.isalnum()
True
s.isalpha()
功能
判断字符串s是否只包含字母,如果是返回True,否则返回False
举例
>>> s1.isalpha()
True
>>> s2.isalpha()
False
>>> s3.isalpha()
False
s.isdigit()
功能
判断字符串s是否只包含数字字符,如果是返回True,否则返回False
举例
>>> s1.isdigit()
False
>>> s2.isdigit()
True
>>> s3.isdigit()
False
s.islower()
功能
判断字符串s是否只包含小写字母,如果是返回True,否则返回False
举例
>>> s1.islower()
True
>>> s2.islower()
False
s.isupper()
功能
判断字符串s是否只包含大写字母,如果是返回True,否则返回False
举例
>>> s4 = 'ABC'
>>> s4.isupper()
True
s.isspace()
功能
判断字符串s是否只包含空白字符,如果是返回True,否则返回False
举例
>>> s5 = ' '
>>> s5.isspace()
True
s.startswith(t)
功能
判断字符串s是否以字符t开头,如果是返回True,否则返回False
举例
>>> s = 'hello, world!'
>>> s.startswith('h')
True
>>> s.startswith('H')
False
s.endswith(t)
功能
判断字符串s是否以字符t结尾,如果是返回True,否则返回False
举例
>>> s = 'hello, world!'
>>> s.endswith('!')
True
>>> s.endswith('.')
False
其他判断函数
s.isidentifier()
功能
判断字符串s是否合法的标识符,如果是返回True,否则返回False
举例
s.isdecimal()
功能
判断字符串s是否只包含十进制数字的字符,如果是返回True,否则返回False
举例
s.isnumeric()
功能
判断字符串s是否只包含数字,如果是返回True,否则返回False
举例
s.isprintable()
功能
判断字符串s是否只包含可打印字符,如果是返回True,否则返回False
举例
s.istitle()
功能
判断字符串s大小写符合头衔要求(title-case),如果是返回True,否则返回False
举例
搜索函数
s.count(t)
功能
搜索字符t,返回字符t在字符串出现的次数
举例
>>> s = 'hello,world!'
>>> s.count('o')
2
>>> s.count('i')
0
s.find(t)
功能
搜索字符t,如果没有找到子串t,则返回-1;否则返回t在s中的起始位置
举例
>>> s = 'hello,world'
>>> s.find('o')
4
>>> s.find('i')
-1
s.index(t)
功能
与find相同,返回t在s中的起始位置,但如果在s中找不到t,则引发ValueError异常
举例
>>> s.index('o')
4
>>> s.index('i')
Traceback (most recent call last):
File "<input>", line 1, in <module>
ValueError: substring not found
s.rfind(t)
功能
与find相同,但从右往左搜索,返回t在s中的最后一次出现时的起始位置索引
举例
>>> s.rfind('o')
7
s.rindex(t)
功能
与index相同,但从右往左搜索,返回t在s中的最后一次出现时的起始位置索引
举例
>>> s.rindex('o')
7
格式函数
s.center(n, t)
功能
包含n个字符的字符串,其中s位于*,两边用字符t填充,t可选
举例
>>> s = 'hello'
>>> s.center(10)
' hello '
>>> s = 'hello'
>>> s.center(10,'-')
'--hello---'
s.ljust(n, t)
功能
包含n个字符的字符串,其中s位于左边,右边用字符t填充,t可选
举例
>>> s = 'hello'
>>> s.ljust(10)
'hello '
>>> s = 'hello'
>>> s.ljust(10,'-')
'hello-----'
s.rjust(n, t)
功能
包含n个字符的字符串,其中s位于右边,左边用字符t填充,t可选
举例
>>> s = 'hello'
>>> s.rjust(10)
' hello'
>>> s = 'hello'
>>> s.rjust(10,'-')
'-----hello'
s.format(vars)
功能
格式化字符串,类似%
字符映射
格式限定
举例
字符映射
>>> '{0},{1}'.format('hello','world')
通过位置
'hello,world'
>>> '{A},{B}'.format(A = 'hello',B = 'world')
通过指定
'hello,world'
格式限定
>>> '{:^10}'.format('hello')
居中对齐
' hello '
>>> '{:<10}'.format('hello')
左对齐
'hello '
>>> '{:>10}'.format('hello')
右对齐
' hello'
S.join(t)
功能
t是一个列表,将列表中的元素用S连接起来
举例
>>> l=['a','b','c']
>>> ' '.join(l)
'a b c'
>>> '-'.join(l)
'a-b-c'
剥离函数
s.strip(t)
功能
从s开头和末尾中的t字符,默认删除空白字符
举例
>>> s = ' hello, world! '
>>> s.strip()
'hello, world!'
s.lstrip(t)
功能
从s开头(左端)删除所有包含在字符串中的t字符,默认删除空格
举例
>>> s = ' hello, world! '
>>> s.lstrip()
'hello, world! '
s.rstrip(t)
功能
从s末尾(右端)删除所有包含在字符串中的t字符,默认删除空格
举例
>>> s = ' hello, world! '
>>> s.rstrip()
' hello, world!'
拆分函数
s.partition(t)
功能
将s拆分为三个字符串(head、t和tail),其中head为t前面的子串,而tail为t后面的子串
举例
>>> s = 'www.pinginglab.net'
>>> s.partition('.')
('www', '.', 'pinginglab.net')
s.rpartition(t)
功能
与partition相同,但从s的右端开始搜索t
举例
>>> s = 'www.pinginglab.net'
>>> s.rpartition('.')
('www.pinginglab', '.', 'net')
s.split(t)
功能
以t为分隔符,将s划分成一系列子串,并返回一个由这些子串组成的列表
举例
>>> s = 'www.pinginglab.net'
>>> s.split('.')
['www', 'pinginglab', 'net']
>>> s = 'Welcome to PINGINGLAB'
>>> s.split()
['Welcome', 'to', 'PINGINGLAB']
s.rsplit(t)
功能
与split相同,但从s的右端开始搜索t
举例
>>> s.rsplit('.')
['www', 'pinginglab', 'net']
s.splitlines()
功能
返回一个由s中的各行组成的列表
举例
>>> s = '''hello,world!
... Welcome to PINGINGLAB'''
>>>
>>>
>>> s.splitlines()
['hello,world!', 'Welcome to PINGINGLAB']
替换函数
s.replace(old, new)
功能
将s中的每个old替换为new
举例
>>> s = 'hello,world!'
>>> s.replace('hello','hi')
'hi,world!'
s.expandtabs(n)
功能
将s中的每个制表符tab替换为n个空格
举例
>>> s = 'hello\tworld'
>>> s.expandtabs(1)
'hello world'
>>> s.expandtabs(5)
'hello world'
大小写函数
s.lower()
功能
让s的所有字母都小写
举例
>>> s = 'Hello,World!'
>>> s.lower()
'hello,world!'
>>> s.upper()
'HELLO,WORLD!'
>>> s.capitalize()
'Hello,world!'
>>> s.title()
'Hello,World!'
>>> s.swapcase()
'hELLO,wORLD!'
s.upper()
功能
让s的所有字母都大写
举例
>>> s = 'Hello,World!'
>>> s.upper()
'HELLO,WORLD!'
s.capitalize()
功能
将s第一个字符改为大写
举例
>>> s.capitalize()
'Hello,world!'
s.swapcase()
功能
将小写字母改为大写,并将大写字母改为小写
举例
>>> s.swapcase()
'hELLO,wORLD!'
s.title()
功能
让s的大小写符合标题化的要求,即所有的单词第一个字符为大写其他小写
举例
>>> s = 'hello,world!'
>>> s.title()
'Hello,World!'
进阶操作
字符编码
编码原理
计算机只能读懂二进制0和1,处理字符时,需要将字符转换为数字存储并处理
将字符与数字相互对应的编码规则称为字符编码(码表)
编码分类
ASCII
概述
最早的字符编码规则称为ASCII编码
ASCII(American Standard Code for Information Interchange,美国标准信息交换代码)
0-127 是ASCII 码的范围,总共128个字符
长度支持
采用1个字节8个比特来表示字符
总共最多255个字符支持
语言支持
只能支持英语
Unicode
概述
随着计算机的普及,各个国家出现了各自的字符编码集,例如中国的GB2312和GBK
由于不同国家不同地区的字符编码相互不支持,为了解决这个问题开发了Unicode(统一码/万国码)字符编码
长度支持
采用2个字节或4个字节来表示字符,一般采用2个
编码方式
Universal Character Set,简称为UCS
UCS-2就是用两个字节编码,UCS-4就是用4个字节编码
UCS编码分为UCS-2和UCS-4两个规范
语言支持
所有国家
UTF-8
概述
Unicode有些字符并不需要2个字节来进行存储和传输,例如英文只需要1个字节即可
Unicode是一个字符编码规范,UTF-8是Unicode的存储和传输的实现方式
UTF-8就是在互联网上使用最广的一种Unicode的实现方式
实现方式
UCS Transformation Format
UTF-8
采用8个比特1个字节作为基础单位
UTF-16
UTF-32
长度支持
可变长编码,采用1到6个字节来存储和传输字符
一般英文用1个字节,汉语用3个字节,比较复杂的用4到6个字节
可以有效节省空间
语言支持
所有国家
编码设置
源代码编码设置
#!/usr/bin/python
为Linux/Unix环境设置环境变量/执行路径
Windows系统忽略
更推荐的做法:#!/usr/bin/env python
#!/usr/bin/python
#!/usr/bin/python直接告知操作系统执行这个脚本的时候,直接调用/usr/bin目录下的python解释器
#!/usr/bin/python写法相当于写死了python路径,如果python默认安装到此路径,则没有任何问题
#!/usr/bin/env python
#!/usr/bin/env python 采用这种写法更加有拓展性,因为有时候python没有安装到默认路径,或者python有多版本的情况
#!/usr/bin/env python3
若指定python3环境
此时系统会到env环境设置里查找python,再调用对应路径下的解释器程序完成操作
# -*- coding: UTF-8 -*-
采用UTF-8编码打开,支持中文
若用其他编码则可能出现乱码
python 2.7 默认为ASCII编码
Python 2.7.6 (default, Sep 9 2014, 15:04:36)
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.39)] on darwin
>>> import sys
>>> print sys.getdefaultencoding()
ascii
>>> ord('a')
97
>>> ord('中')
Traceback (most recent call last):
File "<input>", line 1, in <module>
TypeError: ord() expected a character, but string of length 3 found
python 3.5 默认为UTF-8编码
Python 3.5.1 (v3.5.1:37a07cee5969, Dec 6 2015, 01:54:25) [MSC v.1900 64 bit (AMD64)] on win32
>>> import sys
>>> sys.getdefaultencoding()
'utf-8'
>>> ord('a')
97
>>> ord('中')
20013
编辑器编码设置
设置编码方式为UTF-8
转义字符
转义概述
通过引入转义字符,可以实现字符串中的特殊需求,例如换行、回车等功能
在需要在字符中使用特殊字符时,python用反斜杠(\)转义字符
转义字符
\ 续行符
\\ 反斜杠符号
>>> s = 'hello,\\world'
>>> print s
hello,\world
\' 单引号
>>> s = 'hello,\'world'
>>> print s
hello,'world
\" 双引号
>>> s = 'hello,\"world'
>>> print s
hello,"world
\n 换行
>>> s = 'hello,\nworld'
>>> print s
hello,
world
\t 横向制表符
>>> s = 'hello,\tworld'
>>> print s
hello, world
\v 纵向制表符
\r 回车
\b 退格
\a 响铃
\e 转义
\000 空
\f 换页
\ott 八进制数,tt代表的字符
\xtt 十六进制数,tt代表的字符
关闭转义
>>> s = r'hello,\tworld'
file = open(r'C:\new\test.txt', 'w')
>>> print s
hello,\tworld
格式化字符
格式化概述
通过引入格式化字符,可以实现更加复杂的字符串表达
格式化允许在一条字符串语句执行多字符替换
格式化字符采用%符号来引用
格式化语法
'字符串%d %s’ %( 元素1,元素2,元素3 ……)
左侧
在%操作符的左侧放置一个需要进行格式化的字符串,
这个字符串带有一个或多个嵌入的转换目标,
都以%开头(例如,%d)
右侧
在%操作符右侧放置一个(或多个,嵌入到元组中)对象,
这些对象将会插入到左侧想让Python进行格式化字符串的
一个(或多个)转换目标的位置上去。
格式化字符
%s 格式化字符串
>>> ‘hello, %s’ % ‘J’
‘hello, J’
>>> ‘Hello, %s, Welcome to %s’ % (‘J’, ‘PINGINGLAB’)
‘Hello, J, Welcome to PINGINGLAB’
%d 格式化整数
>>> ‘%s is %d years old’ % (‘J’, 18)
‘J is 18 years old’
>>> x = ‘J’
>>> y = 18
>>> ‘%s is %d years old’ % ( x , y)
‘J is 18 years old’
增强案例
#!/usr/bin/env python
# -- coding: UTF-8 --
a = int(raw_input(‘请输入您的岁数:’))
b = str(raw_input(‘请输入您的名字:’))
c = ‘hello %s,your age is %d’ % (b, a)
print c
%c 格式化字符及其ASCII码
%u 格式化无符号整型
%o 格式化无符号八进制数
%x 格式化无符号十六进制数
%X 格式化无符号十六进制数(大写)
%f 格式化浮点数字,可指定小数点后的精度
%e 用科学计数法格式化浮点数
%E 作用同%e,用科学计数法格式化浮点数
%g %f和%e的简写
%G %f 和 %E 的简写
%p 用十六进制数格式化变量的地址
列表
列表是什么?
定义
列表(List)是一组有序的集合对象类型,可以包括数字、字符串甚至列表等信息。
功能
用于存储其他对象信息
支持复杂的数据存储和处理
语法
变量 = [元素1 , 元素2, 元素3 …… ]
L = ['hello', 123, [10,20] ]
特征
有序
可变
如何操作列表?
操作符
索引操作符
[]
>>> l = ['hello', 123, [10,20]]
>>> l[0]
'hello'
>>> l[1]
123
>>> l[2]
[10, 20]
>>> l[2][0]
10
>>> l[2][1]
20
替换
L[1] = 'hi'
切片操作符
[:]
>>> l = ['hello', 123, [10,20]]
>>> l[0:1]
['hello']
>>> l[0:2]
['hello', 123]
>>> l[0:3]
['hello', 123, [10, 20]]
连接操作符
+
>>> l1 = ['hello',123]
>>> l2 = [456,789]
>>> l1 + l2
['hello', 123, 456, 789]
重复操作符
*
>>> l1 * 3
['hello', 123, 'hello', 123, 'hello', 123]
成员操作符
in
>>> 'hello' in l
True
>>> 'hi' in l
False
not in
>>> 123 not in l
False
内置函数
内置函数
len( )
功能
获取列表的元素个数
举例
>>> len(l)
>>> l = [1,2,3,4,5]
5
max( )
功能
获取列表中最大的值
举例
>>> l = [1,2,3,4,5]
>>> max(l)
5
>>> l2 = ['a','b','c','d','e']
>>> max(l2)
'e'
min( )
功能
获取列表中最小的值
举例
>>> l = [1,2,3,4,5]
>>> min(l)
1
>>> l2 = ['a','b','c','d','e']
>>> min(l2)
'a'
sum( )
功能
将序列的元素相加
举例
>>> l = [1,2,3,4,5]
>>> sum(l)
15
cmp( )
功能
对比两个列表的大小
-1
小于
1
大于
0
相等
举例
>>> l1 = [1,2,3,4,5]
>>> l2 = [2,3,4,5,6]
>>> cmp(l1, l2)
-1
>>> l2 = ['a','b','c','d','e']
>>> cmp(l1,l2)
-1
>>> l3 = ['a','b','c','d','e','f']
>>> cmp(l3,l2)
1
原理
1. 对两个列表的元素进行比较.
-
如果比较的元素是同类型的,则比较其值,返回结果.
-
如果两个元素不是同一种类型,则检查它们是否是数字.
a. 如果是数字,执行必要的数字强制类型转换,然后比较.
b. 如果有一方的元素是数字,则另一方的元素"大"(数字是"最小的")
c. 否则,通过类型名字的字母顺序进行比较. -
如果有一个列表首先到达末尾,则另一个长一点的列表"大".
-
如果我们用尽了两个列表的元素而且所有元素都是相等的,那么结果就是个平局,就 是说返回一个 0.
列表内置函数
列表增加
L.append( )
功能
添加元素到列表末端
举例
>>> l = [1,2,3]
>>> l.append(‘hi’)
>>> l
[1, 2, 3, ‘hi’]
>>> l.append(4)
>>> l
[1, 2, 3, ‘hi’, 4]
L.insert( )
功能
添加元素到具体索引的位置
举例
>>> l = [1,2,3]
>>> l.insert(1,20)
>>> l
[1, 20, 2, 3]
L.extend( )
功能
在本列表的末尾添加其他列表的元素
举例
>>> l1 = [1,2,3]
>>> l2 = [4,5,6]
>>> l1.extend(l2)
>>> l1
[1, 2, 3, 4, 5, 6]
列表删除
L.pop( )
功能
默认删除List末尾的元素,可指定索引删除
举例
>>> l = [1,2,3]
>>> l.pop()
3
>>> l
[1, 2]
>>> l.pop(0)
1
>>> l
[2]
L.remove( )
功能
删除某个指定的元素(第一个匹配项)
举例
>>> l = [1,2,3,1,2]
>>> l.remove(1)
>>> l
[2, 3, 1, 2]
列表搜索
L.count( )
功能
统计某个元素在列表出现的次数
举例
>>> l = [10,20,30,10,20,10]
>>> l.count(10)
3
>>> l.count(30)
1
L.index( )
功能
找出列表某个元素第一个出现的索引位置
举例
>>> l = [10,20,30,10,20,10]
>>> l.index(20)
1
列表排序
L.reverse( )
功能
翻转列表元素位置
举例
>>> l = [1,10,5,15]
>>> l.reverse()
>>> l
[15, 5, 10, 1]
L.sort( )
功能
对列表进行排序(从小到大)
举例
>>> l.sort()
>>> l
[1, 5, 10, 15]
进阶操作
列表解析
概述
列表解析即通过特定的表达式简洁方便生成新的列表
列表迭代
列表生成式
语法
[X for Y in Z]
[X for Y in Z if J]
if J 为判断条件
X为需要得到的结果
X与Y是相关联的
Y是用于遍历Z的参数
Z是被遍历的对象
Z可以是字符串/元祖/列表/字典/函数等可迭代对象
举例
>>> [x + 1 for x in (1,2,3)]
X即x + 1
Y即x
Z即(1,2,3)
[2, 3, 4]
>>> [x for x in ‘hello’]
X即x
Y即x
Z即‘hello’
[‘h’, ‘e’, ‘l’, ‘l’, ‘o’]
>>> [x * x for x in range(1,5)]
[1, 4, 9, 16]
>>> [x + 1 for x in [1,2,3,4,5] if x > 3]
[5, 6]
>>> l1 = [‘hello’,‘world’]
>>> l2 = [x.upper() for x in l1]
>>> l2
[‘HELLO’, ‘WORLD’]
元组
元组是什么?
定义元组(Tuple)是一组有序不可变的集合对象类型,可以包括数字、字符串甚至列表/元组等信息。 相比列表,元组的内容不可变,并且采用小括号来创建,其他特性基本相同。 若对象内容操作时,要求是只读的,建议用元组,更安全 若经常需要修改对象内容时,建议用列表,否则每次对元组进行修改,就必须创建新的元组 通过list( )或tuple( )函数可以实现列表和元组的转换 功能 支持复杂的数据存储和处理 用于存储其他对象信息 语法 变量 = (元素1 , 元素2, 元素3 …… ) T = ('hello', 123, (10,20)) 单元组 T = ('hello',) >>> t = ('hello') >>> t 'hello' >>> t = ('hello',) >>> t ('hello',) 需要加逗号 一些表达式如数学表达式有时候也会用到括号,为了防止歧义,单元组需要加逗号来消除歧义 单列表 >>> l = ['hello'] >>> l ['hello'] >>> l = ['hello',] >>> l ['hello'] 特征 有序 不可变 如何操作元组? 操作符 索引操作符 [] >>> t = ('hello',123,[10,20]) >>> t[0] 'hello' >>> t[1] 123 >>> t[2] [10, 20] >>> t[2][1] 20 替换/修改 >>> t[0] = 'hi' Traceback (most recent call last): File "<input>", line 1, in <module> TypeError: 'tuple' object does not support item assignment >>> t[2][0] = 5 >>> t ('hello', 123, [5, 20]) 切片操作符 [:] >>> t = ('hello',123,[10,20]) >>> t[0:1] ('hello',) >>> t[0:2] ('hello', 123) >>> t[0:3] ('hello', 123, [10, 20]) 连接操作符 + >>> t = ('hello',123) >>> t1 = ('hello',123) >>> t2 = (456,789) >>> t = t1 + t2 >>> t ('hello', 123, 456, 789) 重复操作符 * >>> t = ('hello', 123) >>> t * 2 ('hello', 123, 'hello', 123) 成员操作符 in >>> t = ('hello', 123) >>> 'hello' in t True >>> '456' in t False not in >>> 123 not in t False 内置函数 T.count( ) 功能 统计某个元素在列表出现的次数 举例 >>> t = ('hello',10,20,30,10,20,30) >>> t.count('hello') 1 >>> t.count(10) 2 T.index( ) 功能 找出列表某个元素第一个出现的索引位置 举例 >>> t = ('hello',10,20,30,10,20,30) >>> t.index(10) 1 映射 字典 字典是什么? 定义 字典(dict)是一种无序集合对象类型,可以存储任意的数据类型 字典也是Python中唯一的映射类型,通过"key-value"键值对的方式存储数据 与列表相比,字典是无序的,列表是有序;列表采用偏移位置来存取,字典采用键/散列映射来存取,速度快效率高 列表虽然速度慢,但是内存消耗小 字典虽然速度快,但是内存消耗大 功能 支持复杂的数据存储和处理 用于存储其他对象信息 Python最强大的“容器” 语法 变量 = {键1:值1,键2:值2,……} d = {key1 : value1, key2 : value2,…… } d ={'A':1,'B':2,'C':3} 原理 特征 无序 字典中信息没有按索引位置存储,而是按照散列映射关系存储 可变 键是不可变的,并且必须是唯一的 键值对根据键的散列值作为索引,若键发生变动,则无法找到对应的值 键只能由数字、字符串、元组等不可变对象组成,不能用列表 >>> d ={['a']:1,'B':2,'C':3} Traceback (most recent call last): File "<input>", line 1, in <module> TypeError: unhashable type: 'list' 一个键只能对应一个值 >>> d ={'A':1,'B':2,'C':3,'A':4} >>> d {'A': 4, 'C': 3, 'B': 2} 值是可变的,相同值可以出现在同一字典 如何操作字典? 操作符 查找操作符 d[k] 通过键'k',查询字典中某元素的值 >>> d ={'A':1,'B':2,'C':3} >>> d['A'] 1 d[k] = v 通过键'k',给字典中某元素赋值'v' ;若字典没有本键'k',则新增进来 >>> d ={'A':1,'B':2,'C':3} >>> d['A'] = 10 >>> d {'A': 10, 'C': 3, 'B': 2} >>> d ={'A':1,'B':2,'C':3} >>> d['D'] = 4 >>> d {'A': 1, 'C': 3, 'B': 2, 'D': 4} 成员操作符 in >>> 'A' in d True >>> 'a' in d False not in >>> 'a' not in d True 内置函数 d.items() 功能 返回一个由字典d的键-值对组成的视图(view) 举例 >>> d ={'A':1,'B':2,'C':3} >>> d.items() [('A', 1), ('C', 3), ('B', 2)] d.keys() 功能 返回一个由字典d的键组成的视图 举例 >>> d.keys() ['A', 'C', 'B'] d.values() 功能 返回一个由字典d的值组成的视图 举例 >>> d.values() [1, 3, 2] d.get(key) 功能 返回与key相关联的值 举例 >>> d.get('A') 1 >>> d.get('B') 2 >>> d.get('a') 无报错返回空值 d.pop(key) 功能 删除键key并返回与之相关联的值 举例 >>> d ={'A':1,'B':2,'C':3} {'C': 3, 'B': 2} >>> d >>> d.pop('A') 1 d.popitem() 功能 删除某个键值对,返回字典d中的某个键-值对 举例 >>> d ={'A':1,'B':2,'C':3} >>> d.popitem() ('A', 1) >>> d {'C': 3, 'B': 2} >>> d.popitem() ('C', 3) >>> d {'B': 2} >>> d.popitem() ('B', 2) >>> d {} d.clear() 功能 删除字典d的所有元素 举例 >>> d ={'A':1,'B':2,'C':3} >>> d.clear() >>> d {} d.copy() 功能 (拷贝)复制字典d 举例 >>> d1 = {'A':1,'B':2,'C':3} >>> d2 = d1.copy() >>> d2 {'A': 1, 'C': 3, 'B': 2} d.update(e) 功能 (合并)将e中的键值对添加到字典d中 举例 >>> d1 = {'A':1,'B':2,'C':3} >>> d2 = {'D':4,'E':5,'F':6} >>> d1.update(d2) >>> d1 {'A': 1, 'C': 3, 'B': 2, 'E': 5, 'D': 4, 'F': 6} d.setdefault(key, v) 功能 如果键key包含在字典d中,则返回其值;否则,返回v并将(key, v)添加到字典d中 举例 >>> d ={'A':1,'B':2,'C':3} >>> d.setdefault('D',4) 4 >>> d {'A': 1, 'C': 3, 'B': 2, 'D': 4} d.has_key(key) 功能 判断某个key是否在字典中,如果有返回True,没有返回False 举例 >>> d ={'A':1,'B':2,'C':3} >>> d.has_key('A') True >>> d.has_key('a') False 集合 集合是什么? 定义 集合(set)是一种无序不重复对象类型 集合类似字典,但是只有键,没有值 功能 消除重复元素 将列表中的重复元素消除 实现交、并、差等数学计算 语法 变量 = set(列表/字符串 ) s = set(list) >>> list = [1,2,3,1,2,4] >>> s1 = set(list) >>> s1 set([1, 2, 3, 4]) s = set(str) >>> str = 'hello,world;hi,world' >>> s2 = set(str) >>> s2 set(['e', 'd', 'i', 'h', 'l', 'o', ',', 'r', 'w', ';']) 特征 无序 类似字典,没有序列/索引,不支持切片和索引访问 不重复 每个项在集合中都是唯一的 可变&不可变 可变集合 set( ) 可增加删除元素 不可变集合 frozenset( ) 不可增删 如何操作集合? 操作符 交集 & 功能 获取集合中相同的元素 举例 >>> l1 = [1,2,3,4,5] >>> l2 = [2,3,4,5,6] >>> s1 = set(l1) >>> s1 set([1, 2, 3, 4, 5]) >>> s2 = set(l2) >>> s2 set([2, 3, 4, 5, 6]) >>> s1 & s2 set([2, 3, 4, 5]) 并集 | 功能 将集合中的元素合并 举例 >>> s1 | s2 set([1, 2, 3, 4, 5, 6]) 差集 - 功能 获取集合中的不同元素,不同元素在s1中 举例 >>> s1 - s2 set([1]) ^ 功能 对称差分,获取集合中的不同元素,元素在不同集合中(并集减去交集) 举例 >>> s1 ^ s2 set([1, 6]) 内置函数 交集 s.intersection( ) >>> s1.intersection(s2) set([2, 3, 4, 5]) 并集 >>> s.union( ) >>> s1.union(s2) set([1, 2, 3, 4, 5, 6]) 差集 s.difference( ) >>> s1.difference(s2) set([1]) s.symmetric_difference( ) >>> s1.symmetric_difference(s2) set([1, 6]) 增加 s.add( ) 功能 增加元素 举例 >>> s1 set([1, 2, 3, 4, 5]) >>> s1.add(10) >>> s1 set([1, 2, 3, 4, 5, 10]) >>> s1.add(1) 增加已经存在的元素,集合不改变 >>> s1 set([1, 2, 3, 4, 5, 10]) s.update( ) 功能 增加集合中的元素(集合叠加) 举例 >>> s1.update(s2) >>> s1 set([1, 2, 3, 4, 5, 6, 10]) 删除 s.remove( ) 功能 删除特定元素;若没有该元素则报错 举例 >>> s1 set([1, 2, 3, 4, 5, 6, 10]) >>> s1.remove(1) >>> s1 set([2, 3, 4, 5, 6, 10]) >>> s1.remove(1) Traceback (most recent call last): File "<input>", line 1, in <module> KeyError: 1 s.discard( ) 功能 删除特定元素;若没有该元素不报错 举例 >>> s1 set([2, 3, 4, 5, 6, 10]) >>> s1.discard(1) >>> s1 set([2, 3, 4, 5, 6, 10]) >>> s1.discard(2) >>> s1 set([3, 4, 5, 6, 10]) s.pop( ) 功能 删除一个元素 举例 >>> s1 set([1, 2, 3, 4, 5]) >>> s1.pop() 1 >>> s1 set([2, 3, 4, 5]) 清除 s.clear( ) 功能 清除该集合 举例 >>> s1 set([3, 4, 5]) >>> s1.clear() >>> s1 set([]) 判断 s.issubset 功能 判断s1是否s2的子集 举例 >>> s1 set([1, 2, 3, 4, 5, 6, 7]) >>> s2 set([2, 3, 4, 5, 6]) >>> s1.issubset(s2) False s.issuperset 功能 判断s1包含s2 举例 >>> s1.issuperset(s2) True
4、流程控制
条件语句
if语句
定义
if语句用于实现条件判断,让程序作出简单或复杂的决策。
if…else…if...elif...else 若结果为真则执行,反之不执行(若...则执行...否则...) 举例 若‘你是好学生’ 则 ‘学好Python’;若‘你不是好学生’,则‘回家种田’ 语法 单if条件 if 条件判断1: if条件判断根据代码返回的布尔逻辑结果True或False来进行选择操作 布尔/比较/身份/成员操作能够返回True和False 布尔操作 and or not 比较操作 == != > < > = < = 成员操作 in not in 身份操作 is is not 代码块1 根据PEP规定,Python缩进采用4个空格 一般的IDE和文本编辑器会帮忙自动缩进 用tab可以成功执行,也不是非常符合代码规范 其他程序一般采用花括号来解决代码之间的关系 else: else是可选部分 若没有else部分,则if条件为真时,执行代码块,否则什么都不执行 代码块2 多if条件 if 条件判断1: 代码块1 elif条件判断2: elif 相当于 else if 代码块2 elif条件判断3: 多条件判断中,只要有一个条件为真,则执行后并结束判断 代码块3 …… else: 代码块n 举例 单条件判断 举例1 判断正负数 >>> num = 10 >>> if num > 0 : ... print '正数' python3.0中,print后面的内容需要加括号( ) 2.7.6可加可不加 ... else: ... print '负数' ... 正数 举例2 用户输入一个数字,判断正负数 #!/usr/bin/python # -*- coding: UTF-8 -*- num = input('number: ') 通过input( )函数获取用户输入 n = int(num) 通过int( )整数函数将用户输入转换为整数 if n > 0 : print '正数' else: print '负数' 多条件判断 举例3 判断成绩优良中差 >>> score = 80 >>> if score < 60: ... print '不及格' ... elif 60<= score <= 79: ... print '中等' ... elif 80 <= score <= 100: ... print '优良' ... else: ... pass ... 优良 举例4 用于输入分数,给出判断结果 #!/usr/bin/python # -*- coding: UTF-8 -*- score = int(input('分数: ')) if score < 60: print '不及格' elif 60<= score <= 79: print '中等' ... elif 80 <= score <= 100: print '优良' ... else: ... pass 多条件同时判断 举例5 or表示任意一个条件成立即可 >>> num = 8 >>> if num > 9 or num < 10: ... print 'yes' ... else: ... print 'no' ... yes 举例6 and表示所有条件成立才可以 >> num = 8 >>> if num > 9 and num < 10: ... print 'yes' ... else: ... print 'no' ... no 嵌套条件判断 举例7 if...else...语句嵌套if...else...语句 >>> num = 8 >>> if num < 10: ... print 'yes' ... if num == 8: ... print 'it is 8' ... else: ... print 'it is others' ... else: ... print 'no' ... yes it is 8 优化 num = 7 if num < 10: print '%s < 10' % num if num == 8: print '%s is 8' % num else: print '%s is not 8' % num else: print '%s >= 10' % num 条件表达式 举例8 概述 条件表达式也称为三元操作符,是if语句的缩写格式 如果X为真,则A等于Y,否则A等于Z A = Y if X else Z if X: A = Y else: A = Z 举例 >>> num = 8 >>> A = 10 if num > 0 else 9 >>> if num > 0: ... A = 10 ... else: ... A = 9 ... >>> A 10 >>> A 10 >>> A = 'YES' if True else 'NO' >>> if True: ... A = 'YES' ... else: ... A = 'NO' >>> A 'YES' 循环语句 条件循环 while语句 定义 while语句用于实现条件循环,可以在条件满足的情况下循环执行代码块 若结果为真则执行循环,反之不执行(若...则循环...) 语法 While条件判断: While条件判断根据代码返回的布尔逻辑结果True或False来进行选择操作 与if条件一样 布尔/比较/身份成员操作能够返回True和False 布尔操作 and or not 比较操作 == != > < > = < = 成员操作 in not in 身份操作 is is not 一般在条件判断之前,会有初始语句,例如定义变量初始值等 n = 0 i = 1 循环代码块 重复执行,直到条件不满足 一般包含递增赋值语句,确保循环最终能退出 i = i + 1 举例 举例1 输出1到10 >>> n = 0 >>> while n < 10: ... n = n + 1 ... print n ... 1 2 3 4 5 6 7 8 9 10 举例2 输出0到10数字相加的结果 >>> n = 0 >>> sum = 0 >>> while n < 10: ... sum = sum + n ... n = n + 1 ... print sum ... 0 1 3 6 10 15 21 28 36 45 举例3 while与else结合 >>> n = 0 >>> while n < 10: ... n = n + 1 ... print n ... else: ... n = -n ... print n ... 1 2 3 4 5 6 7 8 9 10 -10 循环语句 for语句 定义 for语句用于实现循环,例如对列表和字符等可迭代对象进行遍历 语法 for X in Y X为变量 Y为可迭代对象 可以是字符串/元祖/列表/字典/函数等可迭代对象 代码块 举例 举例1 遍历字符串 >>> s = 'hello,world' >>> for x in s: ... print x ... h e l l o , w o r l d >>> for a in s: ... print a.upper(), 代替\n ... H E L L O , W O R L D ! 举例2 遍历列表 >>> l = [1,2,3] >>> for x in l: >>> for x in l: ... print x, ... 1 2 3 ... print x ... 1 2 3 举例3 计算和 >>> l = [1,2,3,4,5] >>> sum = 0 >>> for i in l: ... sum = sum + i ... print sum ... 1 3 6 10 15 举例4 计算乘阶 >>> i = 1 >>> for x in [1,2,3,4,5]: ... i = i * x ... print i ... 1 2 6 24 120 举例5 for语句结合else 当循环执行完之后则执行else语句 >>> l1 = [1,2,3,4,5] >>> for i in l1: ... l = i * i ... print l ... else: ... print i ... 1 4 9 16 25 5 举例6 for语句结合range( ) 功能 range( )函数可以生成整数列表 range(x,y)会生成x到y-1的整数列表 range(1,10)会生成1到9的整数列表 语法 完整语法 range(start, end, step) range( )返回一个包括所有k的列表,这里start<=k<end,从start到end
k每次递增step。step不可以为0,否则将发生错误。
若没有给step,只有2个值,则step默认为1
range返回的值不能等于end,可以等于start
简略语法
range( end )
>>> range(5)
[0, 1, 2, 3, 4]
range (start, end)
举例
>>> for x in range(1,10):
… print x
…
1
2
3
4
5
6
7
8
9
>>> i = 1
>>> for x in range(5):
… i = i * (x + 1)
… print i
…
1
2
6
24
120
举例7
for语句结合zip( )
功能
zip( )函数获取多个列表的元素,生成内置元祖的列表
结合for循环语句可以实现多列表并行遍历
语法
for (x,y) in zip (l1, l2)
举例
>>> l1 = [‘a’,‘b’,‘c’,‘d’]
>>> l2 = [1,2,3,4]
>>> zip(l1,l2)
[(‘a’, 1), (‘b’, 2), (‘c’, 3), (‘d’, 4)]
>>> for (x,y) in zip(l1,l2):
… print x , y
…
a 1
b 2
c 3
d 4
举例8
for语句结合map( )
功能
map( )函数将可迭代对象的每个元素传入函数并返回一个列表
语法
map(f, iterable)
[f(x) for x in iterable]
map函数包括函数和可迭代对象(列表等)
当函数为None时,map( )可以实现并行解析
举例
>>> l1 = [‘a’,‘b’,‘c’,‘d’]
>>> l2 = [1,2,3,4]
>>> map(None,l1,l2)
[(‘a’, 1), (‘b’, 2), (‘c’, 3), (‘d’, 4)]
>>> for (x,y) in map(None,l1,l2):
… print x , y
…
a 1
b 2
c 3
d 4
举例9
for语句结合enumerate( )
功能
enumerate( )用于给传入的可迭代对象索引,返回迭代器
语法
>>> for (x,y) in enumerate(迭代对象):
举例
>>> l1 = [‘a’,‘b’,‘c’]
>>> for (x,y) in enumerate(l1):
… print x,y
…
0 a
1 b
2 c
循环控制
break
定义
用于while和for循环中,用于终止整个循环语句
举例
举例1
while语句中使用break,结合if判断,当搜索到某个字符串时,终止遍历
>>> n = 0
>>> while n < 10:
... n = n + 1
... if n == 8:
... break
... print n
...
1
2
3
4
5
6
7
举例2
for语句中使用break,结合if判断,当搜索到某个字符串时,终止遍历
>>> for i in 'Hello,world!':
... if i == ',':
... break
... print 'The letter is: ',i
...
The letter is: H
The letter is: e
The letter is: l
The letter is: l
The letter is: o
continue
定义
用于while和for循环中,用于终止本次循环
举例
>>> for i in 'Hello,world!':
... if i == ',':
检查到字符串“,”时,直接忽略并继续下面的循环执行
... continue
... print 'The letter is: ',i
...
The letter is: H
The letter is: e
The letter is: l
The letter is: l
The letter is: o
The letter is: w
The letter is: o
The letter is: r
The letter is: l
The letter is: d
The letter is: !
pass
定义
用于循环语句、条件语句、函数语句中占空,保证语句完整
举例
>>> for i in 'Hello,world!':
... pass
...
>>> while n < 10:
... pass
用ctrl + c快捷键终止此循环执行
>>> def f():
... pass
...
进阶语句
迭代器
定义
迭代
迭代(Iteration)指的是对可迭代对象进行从头到尾访问/遍历的过程
例如for循环的底层原理就是一个迭代
迭代器
迭代器(Itarator)指的是通过iter( )函数所返回的一个支持next( )方法的对象
迭代方法
iter( )
通过iter( )可以获得可迭代对象
默认可迭代对象没有next( )函数,通过iter( )迭代函数赋予next( )
next( )
返回可迭代对象中的下一个元素,并检查StopIteration异常终止迭代
可迭代对象
有哪些可迭代对象?
列表
元祖
字符串
字典
文件
自身有next( )方法
迭代的原理是什么?
可迭代对象(iterable)在进行遍历/迭代的时候,自动调用iter获取迭代器,自动调用next方法获取下一个元素
例如 for i in [1,2,3] Python自动调用iter( )函数获取迭代器,自动调用next( )函数获得下一个元素
next( )函数检查StopIteration异常并终止迭代
语法
iter( L )
next( L )
举例
举例1
手工迭代列表
>>> l = [1,2,3]
>>> I = iter(l)
>>> I
<listiterator object at 0x10d2b8b50>
>>> I.next()
1
>>> I.next()
2
>>> I.next()
3
>>> I.next()
Traceback (most recent call last):
File "<input>", line 1, in <module>
StopIteration
举例2
手工迭代字典
>>> D = {'a':1, 'b':2, 'c':3}
>>> I = iter(D)
>>> I
<dictionary-keyiterator object at 0x10d2bbaf8>
>>> next(I)
'a'
>>> next(I)
'c'
>>> next(I)
'b'
>>> next(I)
Traceback (most recent call last):
File "<input>", line 1, in <module>
StopIteration
...
举例3
通过try...except...语句自动迭代列表
>>> l = [1,2,3,4,5]
>>> i = iter(l)
>>> i
<listiterator object at 0x10d2b8bd0>
>>> try:
... while True:
... n = i.next()
... print n
... except StopIteration:
... pass
...
1
2
3
4
5
注:等价于for i in l
举例4
通过for语句自动迭代列表
>>> l = [1,2,3,4,5]
>>> for i in l:
... print i
...
1
2
3
4
5
列表解析
定义
列表解析(List comprehensions)主要用于动态的创建列表
列表生成式
列表解析是迭代技术的一个应用,采用for循环和迭代函数动态生成列表,更简洁方便
语法
[X for Y in Z]
[expr for iter_var in iterable]
for循环通过变量iter_var遍历可迭代对象iterable
expr应用于序列的每个成员,最终结果即产生的列表
[X for Y in Z if J]
if J 为判断条件
X为需要得到的结果
X与Y是相关联的
Y是用于遍历Z的参数
Z是被遍历的对象
Z可以是字符串/元祖/列表/字典/函数等可迭代对象
举例
>>> [x + 1 for x in (1,2,3)]
X即x + 1
Y即x
Z即(1,2,3)
[2, 3, 4]
>>> [x for x in 'hello']
X即x
Y即x
Z即‘hello'
['h', 'e', 'l', 'l', 'o']
>>> [x * x for x in range(1,5)]
[1, 4, 9, 16]
>>> [x + 1 for x in [1,2,3,4,5] if x > 3]
[5, 6]
>>> l1 = ['hello','world']
>>> l2 = [x.upper() for x in l1]
>>> l2
['HELLO', 'WORLD']
生成器表达式
定义
生成器是特定的函数, 允许返回一个值, 然后"暂停"代码的执行, 稍后恢复
生成器函数
在 Python 中,带有 yield 的函数被称之为 generator(生成器)
使用yield语句一次返回一个结果,在每个结果之间挂起和继续它们的状态
生成器表达式是生成器的应用,是列表解析和生成器的结合,也是列表解析的拓展
生成器表达式按需返回产生结果的一个对象,而不是返回或构建一整个结果列表
列表解析是直接生产最终的列表,而生成器表达式按需生产内容,相比而言,后者更加节省内存空间
语法
(expr for iter_var in iterable if cond_expr)
列表解析用[ ] 生成器表达式用( )
举例
>>> l1 = [x + 1 for x in (1,2,3)]
利用列表生成式生成列表
>>> l1
列表生成式直接得到最终结果
若可迭代对象体积比较大,则非常占用内存空间
[2, 3, 4]
>>> l2 = (x + 1 for x in (1,2,3))
利用生成器表达式生成列表
>>> l2
<generator object <genexpr> at 0x10d2bf8c0>
生成器表达式不会直接得到最终列表结果,而是按需得到结果
通过next( )函数手工迭代,或者通过for循环工具自动迭代
以此验证生成器是逐步运行逐步挂起,而迭代器是默认全部运行
>>> l2.next()
生成器表达式是可迭代对象,具备next( )函数,用于得到下一个元素
2
>>> l2.next()
3
>>> l2.next()
4
>>> l2.next()
Traceback (most recent call last):
File "<input>", line 1, in <module>
StopIteration
5、函数模块
函数
定义
函数(Function)是一组可重复使用、有特定功能的代码块
功能
可重复使用
减少程序代码量
提高代码可读性
隐藏函数代码块具体实现过程
专注更抽象的逻辑操作
原理
调用函数
语法
函数名(参数)
举例
abs( )
功能
返回给定参数的绝对值
举例
>>> abs(-1)
1
>>> abs(1.2-2.1j)
2.4186773244895647
>>> abs(0.23 - 0.78)
0.55
pow( )
功能
用于进行指数运算
举例
>>> pow(2, 5)
32
>>> pow(5, 2)
25
>>> pow(1+1j, 3)
(-2+2j)
调用说明
通过为函数传入参数,即可得到相关的返回结果
函数使用过程中,我们无需知道函数内部实现原理
不同函数需要的参数个数和类型不同,有些需要多个参数,有些需要字符串/数字/列表参数
创建函数
语法
def 函数名(参数):
函数头由def + 函数名+ (参数)三个部分组成
函数名与变量名称规则一致,可以包括字母、数字、下划线等
括号内可以有参数或者没有参数
'''函数说明'''
文档说明为可选部分
用于解释该函数的功能,对程序员更加友好
一般包括函数的概述、功能、举例
函数内容
函数内容采用4个空格缩进,由变量、参数、表达式等语句组成
return 表达式
return表达式为函数的可选部分
若不包括return表达式,则该函数为“不返回值函数”
相当于return None
若包括return表达式,则该函数为"返回值函数"
举例
1
>>> def hello():
... print 'hello,world!'
...
>>> hello()
hello,world!
2
>>> def hello(name):
... print 'hello',name
...
>>> hello('Jay')
hello Jay
3
>>> def hello(name):
... print 'hello',name
... return name * 2
...
>>> hello('Jay')
hello Jay
'JayJay'
4
>>> def hello(name):
... '''the first function'''
... print 'hello',name
... return name * 2
...
>>> hello('Jay')
hello Jay
'JayJay'
>>> hello.__doc__
通过__doc__方法查看函数说明
'the first function'
函数的参数
位置参数
定义
函数根据位置顺序将实参传入形参
举例
>>> def sum(a,b):
... return a + b
...
>>> sum(1,2)
3
默认参数
定义
函数将部分参数指向默认值,后续可以不用为此参数传入值
若默认参数所在位置有传入值时,则默认参数指定值被覆盖
通过默认参数,可以减低调用函数的难度
函数包含默认参数时,必选参数在前,默认参数在后
举例
>>> def sum(a , b=2):
第二个参数b设置默认值为2
... return a + b
...
>>> x = 1
>>> sum(x)
调用sum函数,a指向x的值,b采用默认值
3
>>> y = 10
>>> sum(x,y)
默认参数可以被覆盖
11
关键字参数
定义
使用关键字参数允许函数调用时参数的顺序与声明时不一致,Python解释器根据参数名匹配参数值
举例
>>> def m(a, b):
... return a * b
...
>>> m (b = 5, a=10)
50
可变长参数
定义
非关键字可变参数(*元祖)
def func(*tuple)
函数通过*获取可变数量的参数,并全部放入元祖
关键字可变参数(**字典)
def func(**dict)
函数通过**获取可变数量的参数,并全部放入字典
举例
*
>>> def f(*args):
此处的打星号的参数,即代表可变长度元祖
... print args
...
>>> f(1)
(1,)
>>> f(1,2)
(1, 2)
>>> def sum(*v):
此处的打星号的参数,即代表可变长度元祖
... s = 0
... for i in v:
... s = s + i
... return s
...
>>> sum(1,2)
3
>>> sum(1,2,3)
6
>>> sum(1,2,3,4)
10
>>> sum(1,2,3,4,5)
15
**
>>> def func(**dict):
... print dict
...
>>> func(x = 1, y = 2, z = 3)
{'y': 2, 'x': 1, 'z': 3}
>>> func(x = 1, y = 2, z = 3, j = 4)
{'y': 2, 'x': 1, 'z': 3, 'j': 4}
混合参数
定义
函数头定义参数列表时,可以同时包含位置参数、默认参数、关键字参数、可变参数
通过混合参数的方式,可以接收和处理更加复杂的内容
混合参数需要按照特定位置放置
位置参数(必备参数)-> 默认参数 -> 可变参数(* -> **)
举例
>>> def func(x, y = 1, *tuple, **dict):
... print x
... print y
... print tuple
... print dict
...
>>> func(10)
10
1
()
{}
>>> func(10,20)
10
20
()
{}
>>> func(10,20,30)
10
20
(30,)
{}
>>> func(10,20,30,40)
10
20
(30, 40)
{}
>>> func(10,20,30,40,z=1)
10
20
(30, 40)
{'z': 1}
>>> func(10,20,30,40,z=1,j=50)
10
20
(30, 40)
{'z': 1, 'j': 50}
>>> func(y = 11, x = 22)
22
11
()
{}
>>> func(y = 11, x = 22, j=33)
22
11
()
{'j': 33}
变量作用域
局部变量
定义
在函数内部定义的变量称为局部变量
变量作用域指的是该变量能够被使用的范围
局部变量只能在其所属函数中使用
在函数外面,不能访问函数的局部变量。
举例
例1
>>> def var(x,y):
... s = x - y
... print s
...
>>> var(5,1)
4
>>> s
s为函数var的变量,由x和y参数的表达式组成
由于s的作用域在函数内部,所以无法在外部调用此变量
Traceback (most recent call last):
File "<input>", line 1, in <module>
NameError: name 's' is not defined
>>> print s
Traceback (most recent call last):
File "<input>", line 1, in <module>
NameError: name 's' is not defined
例2
>>> def A():
... a = 1
... print a
...
>>> def B():
... a = 2
... print a
...
>>> a = 3
>>> A()
1
>>> B()
2
>>> a
3
全局变量
定义
在函数外部定义的变量称为全局变量
全局变量能被整个程序范围调用
举例
例1
>>> name = 'JAY'
>>> def hello():
... print 'Hi', name
...
>>> hello()
Hi JAY
例2
>>> name = 'JAY'
外部变量name
>>> def hello():
... name = 'James'
函数内部变量name
... print 'Hi', name
这里调用变量name,若函数内部有则调用内部,若没有,调用外部;若外部也没有,报错
...
>>> hello()
Hi James
例3
>>> name = 'JAY'
>>> def hello():
... global name
调用外部变量
... name = 'J'
进行重新赋值
... print 'Hi', name
>>> hello()
Hi J
>>> name
外部变量被修改
'J'
进阶
函数式编程
函数式编程是一种高级的编程方法,采用一系列的函数来解决问题
函数式编程是一种面向过程的实现,数据经过函数不断输入输出处理
函数式编程采用高阶函数来实现复杂的处理
什么是高阶函数?
定义
高阶函数是一种高级函数,至少包含以下条件之一:
函数作为参数被传入
函数作为结果被输出
Python可以支持高阶函数,通过高阶函数可以实现函数式编程。
举例
lambda/map/reduce/filter等内置函数、返回函数、递归函数、装饰器等都是高阶函数的应用和实现
支持递归、闭包、装饰器等高级特性
Python实现部分的函数式编程,函数输入允许有变量
纯函数式编程输入没有变量,输出是固定的
含变量的输入,输出结果会发生变动,有副作用
高阶函数
什么叫高阶函数
变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。
举例
变量指向函数
f=abs
abs(-10)
f(-10)
传入函数作为另一函数的参数
def add(x,y,f):
return f(x)+f(y)
内置高阶函数
lambda函数
定义
匿名函数,当需要一个函数,但是不需要这个函数的名字的时候,则可以通过lambda表达式来实现
通过lambda表达式,减少程序中的函数名字和代码量,实现更简洁的代码
语法
lambda 参数:表达式
lambda x, y: x + y
举例
例1
lambda x, y: x + y
等价于
>>> def sum(x, y):
… return x + y
…
>>> sum(1,2)
3
>>> a = lambda x, y: x + y
>>> a(1, 2)
3
例2
>>> b = lambda x, y=2: x + y
>>> b(1)
3
>>> b(4)
6
例3
>>> c = lambda z ????
>>> c(1)
(1,)
>>> c(1,2)
(1, 2)
>>> c(1,2,3)
(1, 2, 3)
map函数
定义
map函数接收两个参数,第一个是函数,第二个是列表(可迭代对象)
将函数作用在序列的每个元素上, 然后创建由每次函数应用组成的返回值列表
map函数能够用列表解析表达式来实现
语法
map( 函数,列表)
举例
>>> map((lambda x: xx), [1,2,3])
>>> def f(x):
… return x * x
…
>>> l = [1,2,3]
>>> map(f,l)
[1, 4, 9]
[1, 4, 9]
列表解析实现
>>> [x * x for x in [1,2,3]]
[1, 4, 9]
习题
利用map()函数,把用户输入的不规范的英文名字,变为首字母大写,其他小写的规范名字。输入:[‘adam’, ‘LISA’, ‘barT’],输出:[‘Adam’, ‘Lisa’, ‘Bart’]。
answer
map(lambda x:x.title,name_list)
reduce函数
定义
reduce跟map类似,也是接收函数和列表
区别在于reduce将列表中两个元素放入函数计算并得到值,然后将此值与列表的下一个元素放入函数计算得到另外一个值
reduce这种“折叠”的处理方式,最终可以得到一个值
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
语法
reduce( 函数,列表)
reduce每次从列表中取出2个元素放入函数
reduce(func, [1, 2, 3])
func(func(1, 2), 3)
举例
1.序列求和的reduce实现
>>> def add(x, y):
… return x + y
…
>>> reduce(add, [1, 3, 5, 7, 9])
>>> reduce( , [1, 3, 5, 7, 9])
25
2.数字列表转换成数[1,3,5,7,9] ->13579
>>> def fn(x, y):
… return x * 10 + y
…
>>> reduce(fn, [1, 3, 5, 7, 9])
13579
3.对2改进实现str转换成int
>>> def fn(x, y):
… return x * 10 + y
…
>>> def char2num(s):
… return {‘0’: 0, ‘1’: 1, ‘2’: 2, ‘3’: 3, ‘4’: 4, ‘5’: 5, ‘6’: 6, ‘7’: 7, ‘8’: 8, ‘9’: 9}[s]
…
>>> reduce(fn, map(char2num, ‘13579’))
13579
4.最终整理成一个str2int函数
def str2int(s):
def fn(x, y):
return x * 10 + y
def char2num(s):
return {‘0’: 0, ‘1’: 1, ‘2’: 2, ‘3’: 3, ‘4’: 4, ‘5’: 5, ‘6’: 6, ‘7’: 7, ‘8’: 8, ‘9’: 9}[s]
return reduce(fn, map(char2num, s))
5.用lambda简化
def str2int(s):
return reduce(lambda x,y: x*10+y, map(lambda s:{‘0’: 0, ‘1’: 1, ‘2’: 2, ‘3’: 3, ‘4’: 4, ‘5’: 5, ‘6’: 6, ‘7’: 7, ‘8’: 8, ‘9’: 9}[s], s))
习题
请编写一个prod()函数,可以接受一个list并利用reduce()求积。
filter函数
定义
filter函数是一个过滤函数,根据True或False来决定最终结果,如果是True则保留下来
语法
filter( 函数,列表)
举例
保留正数
>>> def Pos(n):
… return n > 0
…
>>> filter(Pos,[-1, 1, 0, -2, 3])
[1, 3]
去掉偶数
>>> def odd(n):
… return n % 2 == 1
…
>>> filter(odd,range(10))
[1, 3, 5, 7, 9]
习题
请尝试用filter()删除1~100的素数。
def is_ss(number):
if number == 1:
return True
for i in range(2,number):
if number % i == 0:
return True
return False
print filter(is_ss,[x for x in range(1,101)])
返回函数
定义
函数作为结果被输出
内置函数中如map函数,是将函数作为输入
举例
例1
>>> def sum2(x, y):
... def sum1( ):
... return x + y
... return sum1
...
>>> s = sum2(1, 2)
>>> s()
3
>>> s = sum2(1, 3)
>>> s()
4
例2
>>> def closure( ):
... i = 10
... def clo2( ):
... return i * i
... return clo2
...
>>> c = closure( )
>>> c
<function clo2 at 0x10bc166e0>
>>> c( )
100
闭包
定义
如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure)。
举例
>>> def sum2(x, y):
... def sum1( ):
... return x + y
... return sum1
...
注:函数sum1调用函数sum2的变量x,y
装饰器
定义
装饰器(Decorator)采用函数作为参数,然后对此函数进行装饰,增强其功能
装饰器可以为函数增加功能,但是无需修改原有函数内部结构
装饰器是闭包的高阶应用,闭包是内部函数调用外部函数的变量,装饰器是调用函数
场景
1.初始版本
def f1():
print 'f1'
def f2():
print ‘f2’
def f3():
print ‘f3’
def f4():
print ‘f4’
2.要给初始代码添加验证功能
员工B
叫原来部门的人重新写一个验证程序
员工BB
def f1():
# 验证1
# 验证2
# 验证3
print ‘f1’
def f2():
# 验证1
# 验证2
# 验证3
print ‘f2’
def f3():
# 验证1
# 验证2
# 验证3
print ‘f3’
def f4():
# 验证1
# 验证2
# 验证3
print ‘f4’
f1()
f2()
f3()
f4()
员工BBB
def check_login():
# 验证1
# 验证2
# 验证3
print ‘check ok’
def f1():
check_login()
print ‘f1’
def f2():
check_login()
print ‘f2’
def f3():
check_login()
print ‘f3’
def f4():
check_login()
print ‘f4’
老板的解答
def w1(func):
def inner():
# 验证1
# 验证2
# 验证3
print ‘check ok’
return func()
return inner
@w1
def f1():
print ‘f1’
@w1
def f2():
print ‘f2’
@w1
def f3():
print ‘f3’
@w1
def f4():
print ‘f4’
执行:
f1()
f2()
f3()
f4()
基本执行过程
1.加载w1函数到内存
2.运行@w1
执行w1函数,并将 @w1 下面的 函数 作为w1函数的参数
问题
被装饰的函数如果有参数呢?
#一个参数
def w1(func):
def inner(arg):
# 验证1
# 验证2
# 验证3
return func(arg)
return inner
@w1
def f1(arg):
print ‘f1’
可以装饰具有处理n个参数的函数的装饰器?
def w1(func):
def inner(*args,**kwargs):
# 验证1
# 验证2
# 验证3
return func(*args,**kwargs)
return inner
@w1
def f1(arg1,arg2,arg3):
print ‘f1’
一个函数可以被多个装饰器装饰吗?
def w1(func):
def inner(*args,**kwargs):
# 验证1
# 验证2
# 验证3
return func(*args,**kwargs)
return inner
def w2(func):
def inner(*args,**kwargs):
# 验证1
# 验证2
# 验证3
return func(*args,**kwargs)
return inner
@w1
@w2
def f1(arg1,arg2,arg3):
print ‘f1’
语法
定义装饰器
def deco(func):
def wrapper( ):
函数体包括func( )
return wrapper
定义函数
def func( ):
函数体
装饰函数
@deco
带参数的装饰器
不带参数的装饰器
def func( )
函数体
举例
例1 不带参数的装饰器
>>> def deco(func):
… def wrapper():
… print ‘this is a decorator!’
… return func()
… return wrapper
…
>>> @deco
… def f1():
… print ‘this is a function!’
…
>>> f1()
this is a decorator!
this is a function!
注明
本质上看,上面的装饰器的作用相当于 f1= deco( f1 )
f1函数作为deco函数的输入
例2 带参数的装饰器
>>> def deco(func):
… def wrapper(n):
… print ‘this is a decorator!’, n
… return func(n)
… return wrapper
…
>>> @deco
… def f1(n):
… print ‘this is a function!’
…
>>> f1(‘test’)
this is a decorator! test
this is a function!
>>> f1(‘test2’)
this is a decorator! test2
this is a function
递归函数
定义
若函数内部调用自身,则这个函数便是递归函数
语法
factorial(N) = N! = N * (N-1)! = N * (N-1) * (N-2)! : = N * (N-1) * (N-2) … * 3 * 2 * 1
为了获得 factorial(N)的值, 需要计算 factorial(N-1);为了找到 factorial(N-1), 需要计算 factorial(N-2)等……
举例
计算阶乘n!
>>> def fact(n):
… if n == 1:
… return 1
… else:
… return n * fact(n - 1)
…
>>> fact(5)
120
>>> fact(1)
1
>>> fact(2)
2
>>> fact(3)
6
>>> fact(4)
24
>>> fact(5)
120
生成器
定义
在 Python 中,带有 yield 的函数被称之为 generator(生成器)
生成器是特定的函数, 允许返回一个值, 然后"暂停"代码的执行, 稍后恢复
使用yield语句一次返回一个结果,在每个结果之间挂起和继续它们的状态
通过生成器,可以节省内存空间,使得函数结果散落在不同时间的请求上
语法
yield vs return
return返回结果并结束函数
yield返回结果并挂起当前状态,并于下次再次执行
举例
例1
编写生成器函数
>>> def num( ):
… print ‘first’
… yield 1
… print ‘second’
… yield 2
… print ‘Third’
… yield 3
… print ‘Over’
…
生成生成器对象
>>> n = num()
通过next()函数调用
>>> next(n)
first
1
>>> next(n)
second
2
>>> next(n)
Third
3
>>> next(n)
Traceback (most recent call last):
File “”, line 1, in
StopIteration
Over
例2
>>> def squars(N):
… for i in range(N):
… yield i ** 2
…
>>> s = squars(5)
>>> s.next()
0
>>> s.next()
1
>>> s.next()
4
>>> s.next()
9
>>> s.next()
16
>>> s.next()
Traceback (most recent call last):
File “”, line 1, in
StopIteration
迭代器
迭代器是python中可以记住遍历位置的对象
迭代器只能往后不能往前
迭代器的两个方法
iter()
创建一个迭代器
next()
返回下一个迭代器对象
模块
定义
模块(Module)是一系列函数、变量、类的组成
Python程序是由一系列模块文件组成,一个.py文件就是一个模块
功能
提高代码重用率
需要用到某些函数,直接调用某个模块即可,无需重复编写
提高程序层次性
不同功能模块放入不同的模块,逻辑性和层次性提高
方便协作防止冲突
函数和变量在不同模块下可以有同样命名,但是不会冲突
这样多人协作时,即便命名冲突,也不会干扰
原理
模块创建
用代码编辑器编写代码并保存为py文件
sublime
vim
通过IDE编写模块
#!/usr/bin/env python
# -*- coding:UTF-8 -*-
x = 1
def printx():
'it is a module!'
print x + 2
模块导入
语法
import Module
导入整个模块到内存
不覆盖本地命名空间
采用点号调用函数
Module.Func1
Module.Func2
Module.Func3
不会覆盖本地命名(变量/函数等)
from Module import Func
导入模块某个函数到内存
直接调用此函数
Func1
会覆盖本地某个命名(若本地有)
from Module import *
导入整个模块到内存
覆盖本地命名空间
直接调用此模块所有函数
Func1
Func2
Func3
会覆盖本地所有命名(若本地有)
reload Module
Python只会导入同一模块一次,若再次通过import或者from命令调用同一模块,也不会再次加载,而直接从内存寻找
通过reload关键词可以重新载入该模块(另外一种方式便是重启Python)
若脚本文件有变动,则需要通过reload重新载入
流程
搜索
模块路径
编译
编译成字节码.pyc
执行更快
运行
将模块定义的函数和类等导入运行
说明
一般导入一次之后,再import相同模块则不会再搜索、编译、运行
需要通过reload来实现重新导入
举例
>>> import math
>>> math.sin(10)
-0.5440211108893699
模块路径
搜索路径
程序运行目录
程序运行或安装目录
环境变量PYTHONPATH
PYTHONPATH是设置包含Python程序文件的目录的列表,这些目录可以是用户定义的或平台特定的目录名
标准库模块目录
标准库模块目录存储Python内置的模块文件
Python会自动搜索标准库模块安装在此电脑上的那些目录
.pth文件
查看路径
sys.path
python会将模块搜索的路径统一存储在sys模块中的path变量中
sys.path 包括程序运行路径、PYTHONPATH、标准库路径等,以列表方式存储
>>> import sys
导入sys模块
>>> sys.path
通过path函数查看标准库路径
'/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7','/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-darwin',
'/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python27.zip', '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7',
['/Applications/PyCharm.app/Contents/helpers/pydev', '/Applications/PyCharm.app/Contents/helpers/pydev',
配置路径
通过函数sys.path增加模块搜索路径
Windows
>>> import sys
>>> sys.path
['C:\\Program Files (x86)\\JetBrains\\PyCharm 4.5.3\\helpers\\pydev', 'C:\\Python35\\python35.zip', 'C:\\Python35\\DLLs', 'C:\\Python35\\lib', 'C:\\Python35', 'C:\\Python35\\lib\\site-packages', 'C:\\Users\\jaykingchen\\PycharmProjects\\PL']
>>> sys.path.append("C:\\PATH")
>>> sys.path
['C:\\Program Files (x86)\\JetBrains\\PyCharm 4.5.3\\helpers\\pydev', 'C:\\Python35\\python35.zip', 'C:\\Python35\\DLLs', 'C:\\Python35\\lib', 'C:\\Python35', 'C:\\Python35\\lib\\site-packages', 'C:\\Users\\jaykingchen\\PycharmProjects\\PL', 'C:\\PATH']
>>> import MOD1
C盘路径下创建PATH文件夹并创建MOD1.py模块
print ('hello, world!')
print ('Welcome to PINGINGLAB')
hello, world!
Welcome to PINGINGLAB
Linux/Unix/Mac
>>> import sys
导入sys模块
>>> sys.path
通过path函数查看标准库路径
>>> sys.path.append('/user/pinginglab/')
添加自定义搜索路径
>>> sys.path.append('/users/jaykingchen/MOD')
['/Applications/PyCharm.app/Contents/helpers/pydev', '/Applications/PyCharm.app/Contents/helpers/pydev',
'/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python27.zip', '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7',
'/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7','/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-darwin',
通过环境变量PYTHONPATH增加模块搜索路径
Windows
set PYTHONPATH=c:\python27\lib;
Linux/Unix/Mac
set PYTHONPATH=/usr/local/lib/python
通过文件.pth增加模块搜索路径
在site-packages添加一个路径文件,如sitepath.pth,文件中加入要增加模块所在的路径即可
Windows
C:\python27\site-packages
C:\Python30\Lib\sitepackages
Linux/Unix/Mac
/usr/local/lib/python3.0/site-packages
/usr/local/lib/site-python
/usr/lib/python2.7/site-packages
/usr/local/lib/python2.7/dist-packages
模块互导
概述
模块和模块之间可以相互导入
举例
模块中导入内置模块
#!/usr/bin/env python
# -*- coding:UTF-8 -*-
import math
x = 1
i = 10
def printx():
'it is a module!'
print x + 2
def printmsin():
print math.sin(i)
模块中导入自定义模块(已经有路径)
#!/usr/bin/env python
# -*- coding:UTF-8 -*-
import M3
y = M3.x + M3.i
def printy():
print y * y
模块中导入自定义模块(还没有添加路径)
import sys
sys.path.append('/users/jaykingchen/MOD')
import M3
def printy():
print y * y
y = M3.x + M3.i
拓展
if __name__ == '__main__':
原理
模块直接执行时,这个模块的名字为 __main___
模块被导入时,这个模块的名字便是模块本身
所以,当模块直接执行时,这个判断条件成立,if语句后面的代码可以执行
当模块被导入时,这个判断不成立,if语句后面的代码不被执行
一般情况下,在模块里面的测试代码例如print等输出,我们可以放置在这个判断语句后面,这样其他人调用我们的模块时,则不会有额外的输出
举例
module3.py
#!/usr/bin/env python
# -*- coding:UTF-8 -*-
import math
x = 3
i = 10
def printx():
'The Module3!'
print x + 2
def printsin():
print math.sin(i)
if __name__ == '__main__':
当其他模块调用此模块时,以下代码不执行
print printx()
print printsin()
module4.py
#!/usr/bin/env python
# -*- coding:UTF-8 -*-
import module3
y = module3.x + module3.i
def printy():
print y * y
print printy()
最终结果
169
进阶
命名空间和作用域
定义
名称空间
名称空间(Namespace)是名字和对象的映射
A namespace is a mapping from names to objects
名称空间是一个字典,其中键是名字,值是对象
内建、模块、函数、类都有自己的名称空间
Python的built-in names(包括内置函数,内置常量,内置类型)
模块的全局名称global names(这个模块定义的函数,类,变量)
函数的局部名称local names
名称空间通过__dict___属性和dir( )函数查看
>>> dir(M3)
['C', '__builtins__', '__doc__', '__file__', '__name__', '__package__', 'i', 'math', 'printmsin', 'prints', 'printx', 's', 'x']
>>> list(M3.__dict__.keys())
['prints', '__builtins__', 'printx', '__file__', 'C', '__package__', 'printmsin', 'i', 's', 'x', '__name__', '__doc__', 'math']
作用域
作用域(Scope)即一个作用范围,表示名称空间可被访问的范围
A scope is a textual region of a Python program where a namespace is directly accessible.
语义作用域,变量的作用域完全是由变量在程序文件中源代码的位置而决定的,而不是由函数调用决定。
根据Python的命名空间,可以得到如下的作用域
内部函数的局部作用域
外层函数的局部作用域
模块的全局作用域
Python内置对象的最外层作用域
函数定义了本地作用域,模块定义了全局作用域
LEGB查找原则
当引用一个变量时,Python按以下顺序依次进行查找:从本地变量中,在任意上层函数的作用域,在全局作用域,最后在内置作用域中查找。
第一个能够完成查找的就算成功;变量在代码中被赋值的位置通常就决定了它的作用域。
功能
明确变量使用范围
防止变量名称冲突
举例
例1
Local本地作用域
>>> a = 10
全局作用域
>>> def printa():
本地作用域
... a = 1
有a变量
... print a
根据LEGB搜索规则,直接调用本地变量
...
>>> printa()
1
例2
Enclosing作用域
>>> a = 10
全局作用域
>>> def printA():
Enclosing作用域
... a = 1
... def printa():
... print a + 2
本地作用域
根据LEGB原则,本地Local没有变量a,此时调用Enclosing外部函数a
... printa()
...
>>> printA()
3
>>> print a
全局作用域/命名空间不被影响
10
例3
Global作用域
>>> a = 10
全局作用域
>>> def printa():
本地作用域
没有a变量
... print a
根据LEGB搜索规则,local和enclosing作用域都没有a变量,此时直接调用global变量
...
>>> printa()
10
例4
Bulti-in作用域
>>> def printa():
本地作用域
... print abs(-10)
本地没有abs()函数和变量,通过内置bulti-in作用域查找abs()函数并调用
...
>>> printa()
10
例5
模块互导作用域影响
M1.py
#!/usr/bin/env python
# -*- coding:UTF-8 -*-
x = 1
def printx():
'it is a module!'
print x + 2
M2.py
#!/usr/bin/env python
# -*- coding:UTF-8 -*-
x = 1
s = '测试'
def printx():
'it is a module!'
print x + 2
def prints():
print s
>>> from M1 import *
直接导入M1模块的全局命名空间到内存
>>> print x
1
>>> printx
全局作用域/命名空间下调用printx函数
<function printx at 0x10c2c68c0>
>>> printx()
3
>>>
>>> x = 10
全局作用域下/命名空间下将x值从1修改为10
>>> print x
10
>>> from M2 import *
导入M2模块,M2的命名空间直接覆盖本地全局命名空间
>>> print x
x的值又被修改
1
包(Package)
定义
=>
包(Package)是一种层次化的程序组织结构,由一系列子包和模块组成
上面图片中MOD表示当前目录
d1是MOD下面的第一级目录
d2和d3是d1下面的目录
d2m1/d2m2/d3m1/d3m2是d2和d3里面的模块
类似模块,可以通过import和from...import语法导入,可以通过点号语法访问
与模块最大不同的是,包通常由模块和__init__文件组成
包导入语句的路径中的每个目录内都必须有__init__.py这个文件,否则导入包会失败
__init__.py是一个初始化模块,Python首次导入某个目录时,会自动执行该目录下__init__.py文件中的所有代码
__init__.py文件可以直接是一个空文件,但也可以为包执行初始化语句或设置__all__等变量
语法
import package1.package2.module
from package1.package2 import module
功能
解决模块命名冲突
简化模块搜索路径设置
实现模块与模块之间的关联
方便大型程序层次化组织
方便第三方组件拓展
第三方组件采用包组织来分发
举例
例1
说明
sys.path /Users/jaykingchen/MOD
d1
处于当前工作目录MOD下面
__init__.py
a = 1
print 'dir1'
d2
__init__.py
b = 2
print 'dir2'
d2m1.py
c = 3
print 'it is a module.py'
>>> import d1.d2.d2m1
dir1
dir2
the d2m1.py
>>> d1.a
1
>>> d1.d2
<module 'd1.d2' from '/Users/jaykingchen/MOD/d1/d2/__init__.py'>
>>> d1.d2.b
2
>>> d1.d2.d2m1
<module 'd1.d2.d2m1' from '/Users/jaykingchen/MOD/d1/d2/d2m1.py'>
>>> d1.d2.d2m1.c
3
例2
说明
包导入环境下,采用from...import语句,可以简化模块/函数/变量的调用,无需输入完整路径
>>> from d1.d2 import d2m1
>>> from d1 import d2
>>> d2.b
2
>>> d2.d2m1.c
3
dir1
dir2
the d2m1.py
>>> d2m1.c
3
小结
若包目录中,所有模块名字唯一,则可以通过from...import...语句导入,简化模块中函数和变量等调用
若包目录中,有些模块的名字重叠,则需要通过import语句,之后采用点号语法进行函数/变量调用,保证唯一性
包管理工具
定义
包管理涉及打包、分发、下载、编译、安装等环节
不同环境由不同的包管理工具来执行
工具
distutils
2000年分布
实现包分发、安装功能
通过setup.py执行
Python内置包管理工具
无需通过其他方式安装
setuptools
2004年分布
setuptools是distutils的增强
实现包分发、安装、下载、管理功能
包括easy_install工具,实现包下载
通过ez_setup.py安装setuptools
eggs格式是setuptools引入的文件格式,以.egg为后缀,实现模块快速安装
包格式
eggs
.egg
eggs格式是setuptools引入的文件格式,以.egg为后缀,实现模块快速安装
wheel
.whl
.egg格式的取代
easy_install
2004年分布
所属setuptools工具
distribute
distribute是setuptools的增强版实现,算是setuptools的分支
distribute用来更加容易的打包和分发包,特别是对有依赖的包
pip
2008年分布
pip是easy_install的取代,大量的组件基于原有的setuptools
windws升级最新pip
python -m pip install --upgrade pip
举例
例1
利用distutils打包和安装
准备
dismod.py
dis = 10
def printdis():
print 'it is a test!'
setup.py
#!/usr/bin/env python
# -*- coding:UTF-8 -*-
from distutils.core import setup
setup(
name = 'd1',
version = '1.0',
author = 'PL',
author_email = '[email protected]',
py_modules = ['dismod'],
url = 'www.pinginglab.net',
download_url = 'www.pinginglab.net/download/',
license="LGPL",
description = 'it is a test!',
)
__init__.py
README.txt
'it is a test!'
MANIFEST
# file GENERATED by distutils, do NOT edit
README
dismod.py
setup.py
打包
python setup.py sdisk
创建源码发行包(source distribution)
gztar
tar.gz
默认sdisk发布格式
bztar
tar
zip
python setup.py bdisk
创建二进制发行包(binary distribution)
rpm
python setup.py bdist_rpm
winins
python setup.py bdist_wininst
windows下的exe文件
msi
编译
python setup.py build
可选
安装中包括编译过程
安装
tar -zxvf d1-1.0.tar.gz
解压缩包文件
cd d1-1.0
进入解压后的包目录下
python setup.py install
执行包安装
包含编译过程
注明
linux/unix/mac下用python setup.py install
windows根据exe文件,双击执行
测试
例2
利用Pypi上传包文件
包分发
Pypi
例3
利用pip和easy_install下载
包下载
Pip下载
链接
http://zengrong.net/post/2169.htm
http://jiayanjujyj.iteye.com/blog/1409819
6、面向对象
面向对象编程
对象基础
什么是对象?
Python是一种“面向对象编程”的语言,所以Python语言中,一切皆对象!
Python语言中,所有能够被处理的、被解决的“东西”,都称之为对象(Object)
本质上讲,对象是一组数据以及能处理这些数据的函数
列表、字典、数字、字符串、函数都是对象
对象有各自特性和行为,例如猴子(能上树),树懒(爱睡觉)……
对象的组成
对象的特性
对象是什么?(what)
对象的数据、对象的状态,是一种静态信息。
值value:对象表示的数据项
身份id:唯一性身份标志,是该对象的内存地址,可用内建函数id()获得
类型tpye:对象的类型决定了该对象可以保存什么类型的值,可进行什么样的操作,以及遵循什么样的规则,可以type()获得
对象的行为
对象能做什么?(how)
对象的操作、功能、方法等,是一种动态信息。
我们将能对象能做的,统称为 “方法/属性/操作”
方法method
通过dir( )获得
函数function
操作operation
对象的举例
例子1:人/程序员/小明
特征
名字
小明
身高
170cm
体重
60kg
年龄
18岁
行为
吃饭
学习
工作
敲代码
例如2:物/书籍/《Python秘籍》
特征
书名
类别
页数
价格
行为
存储知识
激发灵感
编程方法
围绕“do"解决、处理、流程为依据来进行编程,称为“面向过程编程”
POP(procedure-oriented programming)
围绕“things"东西、事情、数据为依据来进行编程,称为“面向对象编程”
OOP(object-oriented programming)
举例
我要好好学Python!
面向过程
收集教程
教材
文档
视频
学习语法
项目练手
完成学习
面向对象
对象1
我(人)
对象2
Python(物)
对象3
学习
视频
教材
文档
从学习的流程入手
从学习这件事情的对象分解开始
类的基础
什么是类?
定义
类(Class)是设计蓝图(或模型),用来创建不同类型的对象
Python内置有数字、字符串、列表、字典等对象,这些内置对象有已经规定好的属性和方法
若需要创建新的对象类型,则需要使用类
类是一种数据结构,可以用来定义对象,将数据值和行为特征融合在一起
类指定了对象将包含哪些数据和函数,数据一般是变量即对应值,函数一般我们称之为方法
功能
对事务进行高度抽象
类是对事务的抽象
提高代码重用率
通过子类和超类,实现类的(多重)继承
提高程序层次性
类支持继承
语法
class ClassName :
定义类的名称
class ClassName(object) :
‘class documentation string'
类文档字符串
class_suite
类体(内容)
数据属性
方法属性
举例
例1
>>> class Person:
... 'The Person Class'
... name = 'daxiong'
... age = 10
... def printName(self):
... print self.name
... def printAge(self):
... print self.age
数据属性(变量)
数据属性可以通过构造函数封装起来,方便继承
方法属性(函数)
例2
>>> class Person:
... 'The Person Class'
... def __init__ (self, name, gender, age):
构造函数,用于给实例/对象初始化参数
类中第一个函数必须是self,代表实例/对象本身
... self.name = name
... self.gender = gender
... self.age = age
... def print_gender(self):
... print '%s: %s' % (self.name, self.gender)
... def print_age(self):
... print '%s: %s' % (self.name, self.age)
类的实例
定义
类(Class)是现实世界的抽象的实体以编程形式出现,实例(Instance)则是这些对象的具体化
通过实例化,类的方法/函数才可以调用,这是类的绑定特征
语法
Inst_a = Class( )
创建实例
举例
>>> class Person:
... 'The Person Class'
... def __init__ (self, name, gender, age):
... self.name = name
... self.gender = gender
... self.age = age
... def print_gender(self):
... print '%s: %s' % (self.name, self.gender)
... def print_age(self):
... print '%s: %s' % (self.name, self.age)
>>> DaXiong = Person('DaXiong', 'male', 10)
创建实例DaXiong,并传入三个参数给构造函数
>>> JingXiang = Person('JingXiang', 'Female', 9)
创建实例DaXiong,并传入三个参数给构造函数
>>> DaXiong.name
'DaXiong'
>>> DaXiong.gender
'male'
>>> DaXiong.age
10
>>> JingXiang.print_age()
JingXiang: 9
>>> JingXiang.print_gender()
JingXiang: Female
类的属性
属性概述
类的属性由数据和方法两个部分组成,可以通过点号方式来访问
数据属性存储数据和变量值,方法属性存储操作数据的函数
举例
>>> class Person():
... version = 1.0
数据属性
... def printVer(self):
方法属性
... print self.version
方法调用数据
...
>>> p = Person()
>>> p.version
1.0
>>> p.printVer()
1.0
调用语法
Inst_a. value1
调用类的数据属性(变量值)
Inst_a. method1
调用类的方法属性(函数)
属性操作
属性访问
访问数据属性
定义
数据属性仅仅是所定义的类的变量
数据属性即静态变量和静态数据
语法
类.数据属性
实例.数据属性
举例
>>> class Person:
'The Person Class'
version = 1.0
静态数据
def __init__(self, name, gender, age):
self.name = name
self.gender = gender
self.age = age
def print_gender(self):
print '%s: %s' % (self.name, self.gender)
def print_age(self):
print '%s: %s' % (self.name, self.age)
>>> Person.version
数据属性可以不经过实例化之间由类调用
1.0
>>> DaXiong = Person('Daxiong', 'male', 10)
>>> DaXiong.version
实例也可以调用数据属性
1.0
访问方法属性
定义
类中所定义的函数,称之为方法
方法有应用范围的,只能在类里面
要调用方法,必须先实例化
原理
类函数规则
①类内部函数与其他函数没有太大区别
例如默认参数、关键字参数等
②类中所有函数第一个参数必须是self
功能
self就是代表实例自己
创建实例时,实例名代替self
举例
>>> class Person():
... version = 1.0
数据属性
... def printVer(self):
定义函数printVer,第一个参数为self
... print self.version
方法调用数据
...
>>> p = Person()
执行实例的时候,printVer会自动将p这个实例传入self
>>> p.printVer()
此时self.version即p.version
1.0
反例
>>> class Person():
... version = 1.0
... def printVer():
注意,这里没有写入self关键字
... print self.version
>>> P = Person()
创建实例P
>>> P.printVer()
实例调用函数printVer
Traceback (most recent call last):
File "<input>", line 1, in <module>
TypeError: printVer() takes no arguments (1 given)
调用函数时,实例P将自己传入;但是因为没有加入self关键字,所以无法传入
③很多类的第一个函数是__init__构造函数
功能
__init__构造函数用于初始化对象值
通过__init__,在创建实例的时候,不能传入空参数,必须传入与__init__方法匹配的参数
构造器一方面做了约束(不能随意调用),一方面提供了便捷(提供了初始参数)
举例
没有构造器的类
>>> class Person:
... version = 1.0
... def setVer(self, v):
创建设置函数
... self.ver = v
... def printVer(self):
... print self.ver
...
>>> p1 = Person()
>>> p1.setVer(2.0)
先设置函数
>>> p1.printVer()
再打印函数
2.0
>>> p2 = Person()
>>> p2.setVer(3.0)
>>> p2.printVer()
3.0
有构造器的类
>>> class Person:
... version = 1.0
... def __init__(self, v):
通过构造器,第一次创建实例时,就直接传入参数
... self.v = v
... def printVer(self):
... print self.v
>>> p1 = Person()
Traceback (most recent call last):
File "<input>", line 1, in <module>
TypeError: __init__() takes exactly 2 arguments (1 given)
>>> p1 = Person(2.0)
>>> p1.printVer()
2.0
语法
①先实例化
②实例.方法
举例
>>> class Person:
... 'The Person Class'
... def __init__ (self, name, gender, age):
... self.name = name
... self.gender = gender
... self.age = age
... def print_gender(self):
... print '%s: %s' % (self.name, self.gender)
... def print_age(self):
... print '%s: %s' % (self.name, self.age)
>>> DaXiong = Person('DaXiong', 'male', 10)
创建实例DaXiong,并传入三个参数给构造函数
>>> JingXiang = Person('JingXiang', 'Female', 9)
创建实例DaXiong,并传入三个参数给构造函数
>>> DaXiong.name
调用构造函数中的变量
'DaXiong'
>>> DaXiong.gender
'male'
>>> DaXiong.age
10
>>> JingXiang.print_age()
调用类中的方法
JingXiang: 9
>>> JingXiang.print_gender()
调用类中的方法
JingXiang: Female
>>> Person.print_gender()
绑定
Python严格要求,没有实例,方法/函数都不能被调用的,这种限制称为绑定
Traceback (most recent call last):
File "<input>", line 1, in <module>
TypeError: unbound method print_gender() must be called with Person instance as first argument (got nothing instead)
属性修改
举例
>>> class Person:
'The Person Class'
version = 1.0
静态数据
def __init__(self, name, gender, age):
self.name = name
self.gender = gender
self.age = age
def print_gender(self):
print '%s: %s' % (self.name, self.gender)
def print_age(self):
print '%s: %s' % (self.name, self.age)
>>> Person.version
数据属性可以不经过实例化之间由类调用
1.0
>>> DaXiong = Person('Daxiong', 'male', 10)
>>> DaXiong.version
实例也可以调用数据属性
1.0
>>> DaXiong.version = 2.0
实例可以对属性进行修改
>>> DaXiong.version
2.0
>>> Person.version
实例属性修改不影响类的属性
1.0
>>> DaXiong.age = 11
修改传入的参数
>>> DaXiong.age
11
增加属性
>>> DaXiong.score = 59
增加一个score属性,并赋值为59
>>> DaXiong.score
59
查看属性
dir( )
>>> dir(DaXiong)
['__doc__', '__init__', '__module__', 'age', 'gender', 'name', 'print_age', 'print_gender', 'score', 'version']
__dict__
>>> DaXiong.__dict__
{'gender': 'male', 'age': 11, 'version': 2.0, 'name': 'Daxiong', 'score': 59}
特殊类属性
说明
这里的特殊类属性以__value__方式命名,前后都有2个下划线
特殊类属性是Python内置属性,所有创建的类默认都有
C.__doc__ 类C的文档字符串
>>> Person.__doc__
'The Person Class'
C.__dict__ 类C的属性
>>> Person.__dict__
{'__module__': '__builtin__', 'print_age': <function print_age at 0x106132b18>, 'print_gender': <function print_gender at 0x1061329b0>, 'version': 1.0, '__doc__': 'The Person Class', '__init__': <function __init__ at 0x1061328c0>}
C.__name__: 类名
C.__module__ 类C定义所在的模块
>>> Person.__module__
'__builtin__'
C.__bases__ : 类的所有父类构成元素
类的进阶
继承
定义
当编写一个类(Class)时,可以从之前的类进行继承,这样可以获取之前的类的所有属性
新的类称为子类(Subclass),而被继承的类被称为基类/父类/超类(Superclass)
有些文档将子类称为派生类(Derived class),超类称为基类(Base class)
错误
狗属于哺乳动物
蜥蜴属于爬行动物
语法
>>> class Parent(object):
……
>>> class Child(Parent):
子类在父类上创建
举例
创建子类
继承判断函数
isinstance( )
>>> isinstance(DaXiong, Male)
True
>>> isinstance(DaXiong, Female)
False
>>> isinstance(JingXiang, Female)
True
issubclass( )
>>> issubclass(Male, Person)
True
>>> issubclass(Female, Person)
True
>>> class Person:
'The Person Class'
def __init__(self, name, gender, age):
self.name = name
self.gender = gender
self.age = age
def print_gender(self):
print '%s: %s' % (self.name, self.gender)
def print_age(self):
print '%s: %s' % (self.name, self.age)
class Male(Person):
'The Male Class'
pass
class Female(Person):
'The Female Class'
pass
>>> DaXiong = Male('Daxiong','male',10)
JingXiang = Female('JingXiang', 'female', 9)
>>> DaXiong.print_gender()
Daxiong: male
>>> JingXiang.print_age()
JingXiang: 9
方法定制
说明
类中的继承方法搜索规则:实例 -> 子类 -> 父类
子类除了继承父类的属性,还可以自己添加、定制、拓展更多功能
若子类的属性与父类属性名字相同,则以子类属性为主,即子类将父类的方法重写或拓展
定制方法
>>> class Person:
'The Person Class'
def __init__(self, name, gender, age):
self.name = name
self.gender = gender
self.age = age
def print_gender(self):
print '%s: %s' % (self.name, self.gender)
def print_age(self):
print '%s: %s' % (self.name, self.age)
class Male(Person):
'The Male Class'
def print_gender(self):
子类中方法与父类相同,则根据继承搜索规则,子类方法优先
print 'He is %s' % self.gender
class Female(Person):
'The Female Class'
def print_gender(self):
子类中方法与父类相同,则根据继承搜索规则,子类方法优先
print 'She is %s' % self.gender
>>> DaXiong = Male('Daxiong','male',10)
>>> JingXiang = Female('JingXiang', 'female', 9)
>>> DaXiong.print_gender()
He is male
>>> JingXiang.print_gender()
She is female
定制构造函数
>>> class Person:
'The Person Class'
def __init__(self, name, gender, age):
self.name = name
self.gender = gender
self.age = age
def print_gender(self):
print '%s: %s' % (self.name, self.gender)
def print_age(self):
print '%s: %s' % (self.name, self.age)
class Male(Person):
'The Male Class'
def __init__(self, name, age):
默认情况下,构造函数从父类继承;但是有时候有一些参数有默认值,可以直接指定,无需再传入
此时可以对构造函数进行改造
Person.__init__(self, name, 'male', age)
调用父类函数,并进行修改
此处将父类构造函数中的性别直接赋值默认参数‘male'
def print_gender(self):
print 'He is %s' % self.gender
class Female(Person):
'The Female Class'
def __init__(self, name, age):
Person.__init__(self, name, 'female', age)
def print_gender(self):
print 'She is %s' % self.gender
>>> DaXiong = Male('Daxiong', 10)
>>> JingXiang = Female('JingXiang', 9)
>>> DaXiong.gender
'male'
>>> JingXiang.gender
'female'
多重继承
定义
多重继承用于实现子类对多个父类的继承
通过多重继承,可以混合不同类的功能,实现更加复杂的需求
语法
class A( ):
class B( ):
class C(A, B ):
举例
>>> class Person:
'The Person Class'
def __init__(self, name, gender, age):
self.name = name
self.gender = gender
self.age = age
def print_gender(self):
print '%s: %s' % (self.name, self.gender)
def print_age(self):
print '%s: %s' % (self.name, self.age)
class Male(Person):
'The Male Class'
def print_gender(self):
print 'He is %s' % self.gender
class Female(Person):
'The Female Class'
def print_gender(self):
print 'She is %s' % self.gender
class Fat(Person):
'The Fat Class'
def print_weight(self):
print 'Fat!'
class Thin(Person):
'The Thin Class'
def print_weight(self):
print 'Thin!'
class MF(Male, Fat):
多重继承
pass
class FT(Female, Thin):
多重继承
pass
>>> DaXiong = MF('Daxiong', 'male', 10)
>>> JingXiang = FT('JingXiang', 'female', 9)
>>> print DaXiong.print_gender()
print DaXiong.print_age()
print DaXiong.print_weight()
print JingXiang.print_gender()
print JingXiang.print_age()
print JingXiang.print_weight()
He is male
Daxiong: 10
Fat!
She is female
JingXiang: 9
Thin!
多态
定义
多态是面向对象语言的一个基本特性,多态意味着变量并不知道引用的对象是什么,根据引用对象的不同表现不同的行为方式
举例
>>> class Person:
'The Person Class'
def __init__(self, name, gender, age):
self.name = name
self.gender = gender
self.age = age
def print_gender(self):
print '%s: %s' % (self.name, self.gender)
def print_age(self):
print '%s: %s' % (self.name, self.age)
class Male(Person):
'The Male Class'
def print_gender(self):
print 'He is %s' % self.gender
class Female(Person):
'The Female Class'
def print_gender(self):
print 'She is %s' % self.gender
>>> DaXiong = Male('Daxiong', 'male', 10)
>>> JingXiang = Female('JingXiang', 'female', 9)
>>> from random import choice
>>> obj = choice([DaXiong,JingXiang])
>>> print obj.print_gender()
He is male
>>> obj = choice([DaXiong,JingXiang])
>>> print obj.print_gender()
She is female
私有变量
定义
默认情况下,类内部所定义的变量通过点号方法可以访问并修改,这种变量称为公有变量
公有变量可被用户修改,导致对象内部状态不一致,此时便需要私有变量(Private)
私有变量即在原有变量的前面加上两个下划线,例如_ _ value
举例
例1 常规公有变量能被访问并修改
>>> class Person:
'The Person Class'
def __init__(self, name, gender, age):
self.name = name
self.gender = gender
self.age = age
>>> DaXiong = Person('Daxiong', 'male', 10)
>>>
>>> DaXiong.age = 20
>>> DaXiong.gender = 'Male'
>>> DaXiong.gender = 'female'
>>> DaXiong.age
20
>>> DaXiong.gender
'female'
例2 通过私有变量实现访问限制
>>> class Person:
'The Person Class'
def __init__(self, name, gender, age):
self.__name = name
私有变量加入两个下划线
self.__gender = gender
self.__age = age
DaXiong = Person('Daxiong', 'male', 10)
>>> DaXiong.name
常规的句点访问方式被拒绝
Traceback (most recent call last):
File "<input>", line 1, in <module>
AttributeError: Person instance has no attribute 'name'
>>> DaXiong._Person__name
通过点号方式中加入类名可以访问,但是不建议
'Daxiong'
例3 通过获取函数实现私有变量值访问
>>> class Person:
'The Person Class'
def __init__(self, name, gender, age):
self.__name = name
self.__gender = gender
self.__age = age
def print_gender(self):
print '%s: %s' % (self.__name, self.__gender)
def print_age(self):
print '%s: %s' % (self.__name, self.__age)
DaXiong = Person('Daxiong', 'male', 10)
JingXiang = Person('JingXiang', 'female', 9)
>>> DaXiong.print_age()
Daxiong: 10
>>> DaXiong.print_gender()
Daxiong: male
>>> JingXiang.print_age()
JingXiang: 9
>>> JingXiang.print_gender()
JingXiang: female
例4 通过设置函数设置条件变量
>>> class Person:
'The Person Class'
def __init__(self, name, gender, age):
self.__name = name
self.__gender = gender
self.__age = age
def set_gender(self,gender):
self.__gender = gender
def set_age(self,age):
if 0 <= age <= 100:
self.__age = age
def print_gender(self):
print '%s: %s' % (self.__name, self.__gender)
def print_age(self):
print '%s: %s' % (self.__name, self.__age)
>>> DaXiong = Person('Daxiong', 'male', 10)
>>> DaXiong.print_age()
Daxiong: 10
>>> DaXiong.set_age(101)
>>> DaXiong.print_age()
Daxiong: 10
>>> DaXiong.set_age(20)
>>> DaXiong.print_age()
Daxiong: 20
装饰器
@property
定义
私有变量章节中,我们通过获取和设置函数,实现更安全的访问和设置
但是,在进行访问和设置时,相对显得比较麻烦?
有没有更好的方式?实现以下的需求=>
既能检查参数,又能像属性一样方便地访问和修改类的变量
可以让调用者写出简短的代码,同时保证对参数进行必要的检查
这就需要 @property 装饰器来实现了
Python内置
举例
>>> class Person(object):
def __init__(self, name, gender, age):
self.__name = name
self.__gender = gender
self.__age = age
@property
获取函数的主要功能是获取变量值
在下面score函数前,加入@property装饰器,表示这是一个获取函数(.getter)
def age(self):
return self.__age
@age.setter
@property + @.setter 实现函数可读写
设置函数的主要功能是实现变量有条件地赋值
@property 实现函数只读
在获取函数score的基础上,加入setter设置函数
def age(self, value):
if value < 0 or value > 100:
raise ValueError('Invalid age!')
self.__age = value
>>> DaXiong = Person('DaXiong', 'Male', 10)
>>> DaXiong.age
10
>>> DaXiong.age = 200
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "<input>", line 15, in age
ValueError: Invalid age!
>>> DaXiong.age = 20
>>> DaXiong.age
20
变量访问和修改变得更简单,变量修改需要依据特定规则
7、输入输出
输入输出
输入输出?
内存<-->硬盘
CPU<-->内存
硬盘<-->网卡
键盘<-->屏幕
文件打开<-->文件关闭
屏幕输出
print
功能
用于打印(输出)信息到屏幕(例如字符串或表达式)
语法
print 字符串
print 'hello, world!'
print 表达式
x = 1
y = 2
print x + y
版本
2.x版本是一个语句
3.x版本是一个函数
3.x版本需要加一个括号
举例
print '这是一个print打印函数'
print 'a','b','c'
print '1 + 1'
print (1 + 1)
键盘输入
raw_input
功能
用于接收键盘输入
语法
i = raw_input( )
举例
s = raw_input('请输入您的账号:')
print '您的账号是:', s
input
功能
用于接入键盘输入,输入内容可以是表达式
语法
i = input( )
举例
s = input('请输入您的公式:')
#input可以输入表达式,然后返回计算结果
print '您的结果是:', s
文件处理
文件打开
语法
file_object = open(file_name, access_mode, buffering)
文件分类
文本文件
使用文本编辑器可以修改
html
doc
xls
ppt
txt
可以被我们阅读和理解
相比二进制文件,体积更大一些
二进制文件
需要专门的文件编辑器来打开
图片
jpg
bmp
gif
视频
mp4
wmv
mkv
程序能阅读和理解
相比文本文件,体积更小一些
文件名称
file_name 是包含要打开的文件名字的字符串, 它可以是相对路径或者绝对路径
打开模式
r
r
以只读方式打开文件
r+
以读写方式打开文件
rb
以二进制方式只读打开文件
rb +
以二进制读写打开文件
w
w
以写入方式打开文件
若文件存在,则覆盖
若文件不存在,则创建
w+
以读写方式打开文件
若文件不存在,则创建
若文件存在,则覆盖
wb
以二进制方式写入打开文件
若文件存在,则覆盖
若文件不存在,则创建
wb +
以二进制方式读写打开文件
若文件存在,则覆盖
若文件不存在,则创建
a
a
以增加方式打开文件,文件指针放在原有内容后面
若文件不存在,则创建
a +
以读写方式打开文件,文件指针放在原有内容后面
若文件不存在,则创建
ab
以二进制方式打开文件并增加内容,文件指针放在原有内容后面
若文件不存在,则创建
ab +
以二进制方式读写文件并增加内容,文件指针放在原有内容后面
若文件不存在,则创建
缓存大小
如果buffering的值被设为0,就不会有寄存。
如果buffering的值取1,访问文件时会寄存行。
如果将buffering的值设为大于1的整数,表明了这就是的寄存区的缓冲大小。
如果取负值,寄存区的缓冲大小则为系统默认。
举例
file1 = open('newfile.txt')
file1 = open('newfile.txt', 'r')
file1 = open('newfile.txt', 'w')
file1 = open('newfile.txt', 'a')
file1 = open('/Users/jaykingchen/PycharmProjects/PINGINGLAB/newfile.txt', 'w')
文件关闭
语法
file.close()
关闭文件,结束文件调用,节省内存空间
举例
file1 = open('newfile.txt', 'w')
print file1.mode
print file1.name
file1.close()
文件写入
语法
file.write()
write()方法不会在字符串的结尾添加换行符\n,若需要换行,需自行添加
举例
file1 = open('newfile.txt', 'wb')
file1.write('www.pinginglab.net\nthe way to learn network\n')
file1.close()
文件读取
语法
file.read()
读取文件所有字节,可以指定字节数,不指定或未负则读取所有
file.readline()
读取一行
包括'\n'字符
file.readlines()
读取所有行并返回列表
每行返回列表
举例
例1
file1 = open('newfile.txt', 'r')
s = file1.read()
print s
file1.close()
例2
file1 = open('newfile.txt', 'r')
s = file1.read(5)
print s
file1.close()
例3
file1 = open('newfile.txt', 'r')
s = file1.readline()
print s
file1.close()
例4
file1 = open('newfile.txt', 'r')
s = file1.readlines()
print s
file1.close()
文件增加
语法
file = open('file_name', 'a')
以a方式打开,代表不覆盖原来内容,在原有基础上增加
file.write()
举例
file1.write('123456\n')
file1.close()
file1 = open('newfile.txt', 'a')
文件偏移
语法
file.tell( )
表示当前指针所在的位置
file.seek( )
指定指针偏移的位置
file.seek(off, whence=0) 在文件中移动文件指针, 从 whence ( 0 代表文件其始, 1 代表当前位置,2 代表文件末尾)偏移 off 字节
举例
tell
file1 = open('newfile.txt', 'r+')
print file1.tell()
file1.write('add line 1\n')
print file1.tell()
file1.write('add line 2\n')
print file1.tell()
file1.close()
seek
file1 = open('newfile.txt', 'w+')
print file1.tell()
file1.write('add line 1\n')
print file1.tell()
file1.write('add line 2\n')
print file1.tell()
file1.seek(-10,1)
print file1.tell()
file1.seek(0, 0)
print file1.tell()
file1.close()
文件重命名
语法
import os
导入系统模块
os.rename('原文件名称','重命名文件名称')
举例
import os
os.rename('newfile.txt', 'nf.txt')
文件删除
语法
import os
导入系统模块
os.remove('文件名称')
举例
import os
os.remove('nf.txt')
目录处理
os模块
获取目录
语法
os.getcwd()
获取当前工作目录
举例
import os
os.getcwd()
创建目录
语法
os.mkdir()
创建新的目录
举例
import os
os.mkdir('newdir')
删除目录
语法
os.rmdir( )
删除指定目录
举例
import os
os.rmdir('newdir')
目录内容
语法
os.listdir()
列出指定目录下的文件和文件夹
举例
import os
os.listdir(os.getcwd())
移动目录
语法
os.chdir()
移动当前工作目录到其他目录
举例
import os
os.chdir('newdir')
os.path模块
查询文件
语法
os.path.isfile
举例
>>> os.path.isfile('newfile.txt')
False
>>> file1 = open('newfile.txt', 'w')
>>> os.path.isfile('newfile.txt')
True
查询目录
语法
os.path.isdir
举例
>>> os.path.isdir('testdir')
True
查看大小
语法
os.path.getsize
举例
>>> os.path.getsize('newfile.txt')
0
>>> file1 = open('newfile.txt', 'w')
>>> file1.write('123')
>>> file1.close()
>>> os.path.getsize('newfile.txt')
3
序列化
概述
我们用Python对象(变量/函数/方法)所进行的操作是在内存中,若Python程序(或系统)关闭,则内存被清除
为了将我们所操作的内容永久存储(保存到硬盘),需要引入"序列化"(顺序化),即pickling/serialization
pickling,serialization,marshalling,flattening
序列化将复杂数据结构(对象)转换为一个二进制数据集合(数据流), 这样就可以把数据永久存储或通过网络发送, 然后再重新把数据流恢复原来的对象内容
变量/对象等从内存中变成可存储或传输的过程称之为序列化
pickling
功能
提供Python对象的序列化和存储转换功能
函数
pickling.dump( )
接收一个文件句柄和一个数据对象作为参数, 把数据对象以特定格式保存到给定文件里
pickling.load( )
从文件中取出已保存的对象时, pickle 知道如何恢复这些对象到它们本来的格式
举例
例1
>>> import pickle
>>> a = 1
>>> pickle.dumps(a)
将对象序列化
'I1\n.'
>>> b = 'hello,world!'
>>> pickle.dumps(b)
将对象序列化
"S'hello,world!'\np0\n."
例2
>>> a = 'hello,world!'
创建一个变量,指向字符串
>>> f = open('dump.txt', 'wb')
创建一个文件dump.txt
>>> pickle.dump(a, f)
将变量序列化存储到dump.txt文件中
S'hello,world!'
p0
.
>>> f.close()
需要保存关闭才能看到成功
例3
>>> f = open('dump.txt', 'rb')
打开dump文件
>>> d = pickle.load(f)
加载dump文件
>>> f.close( )
>>> d
验证反序列化(是否可以得到之前所创建的对象)
'hello,world!'
marshal
功能
提供类似字典和文件的对象,可以完成字符串的永久性存储
举例
shelve
功能
同时具备pickling和marshal的功能
举例
8、异常处理
异常概述
背景
什么是异常?举个例子,我们将“建房子”看出一个程序,这里涉及到材料准备、图纸设计、装修施工等各个环节
整个建房子的过程,可能出现各种各样的问题,材料是否准备充足?施工方是否人员到齐?设计是否有存在问题?装修是否有偷工减料?
“建房子”这事情一个系统工程,任何一个环节出现问题,这个事件就无法进行,例如没有材料或者工人没到场等等;这里程序运行就相当于“建房子”的过程
定义
程序运行会出现各种各样的问题,例如语法编写错误或文件读写错误等,出现各种各样的bug(八阿哥)
默认情况下,程序会马上停止执行,并根据错误情况,反馈异常情况(显示栈追踪)
方便程序员进行排错和调试
哪个位置出了问题?
哪种类型的错误?
本质上讲,异常是一种类,并且有很多子类,基类为BaseException
举例
IOError
异常说明
输入输出异常
异常代码
file1 = open('file.txt','r')
异常输出
Traceback (most recent call last):
File "/Users/jaykingchen/PycharmProjects/PINGINGLAB/6.Errors & Exceptions/IOError.py", line 1, in <module>
file1 = open('file.txt','r')
IOError: [Errno 2] No such file or directory: 'file.txt'
Process finished with exit code 1
ZeroDivisionError
异常说明
分母为0异常
异常代码
a = 1
b = 0
print a / b
异常输出
Traceback (most recent call last):
File "/Users/jaykingchen/PycharmProjects/PINGINGLAB/6.Errors & Exceptions/ZeroDivisionError.py", line 3, in <module>
print a / b
ZeroDivisionError: integer division or modulo by zero
Process finished with exit code 1
TypeError
异常说明
类型异常,操作对本类型失效
异常代码
a = 1
b = 'hello'
print a + b
异常输出
Traceback (most recent call last):
File "/Users/jaykingchen/PycharmProjects/PINGINGLAB/6.Errors & Exceptions/TypeError.py", line 3, in <module>
print a + b
TypeError: unsupported operand type(s) for +: 'int' and 'str'
Process finished with exit code 1
ValueError
异常说明
参数异常,无效的参数
异常代码
num = int('a')
print num
异常输出
Traceback (most recent call last):
File "/Users/jaykingchen/PycharmProjects/PINGINGLAB/6.Errors & Exceptions/ValueError.py", line 1, in <module>
num = int('a')
ValueError: invalid literal for int() with base 10: 'a'
Process finished with exit code 1
SyntaxError
异常说明
语法异常
异常代码
a = 1 +
异常输出
File "/Users/jaykingchen/PycharmProjects/PINGINGLAB/6.Errors & Exceptions/SyntaxError.py", line 1
a = 1 +
^
SyntaxError: invalid syntax
NameError
异常说明
名字异常,对象未定义
异常代码
a = 1
print a + b
异常输出
Traceback (most recent call last):
File "/Users/jaykingchen/PycharmProjects/PINGINGLAB/6.Errors & Exceptions/NameError.py", line 2, in <module>
print a + b
NameError: name 'b' is not defined
Process finished with exit code 1
AttributeError
异常说明
属性异常,对象没有此属性/方法
异常代码
a = 1
b = 'hello'
b.coun()
print b,a
异常输出
Traceback (most recent call last):
File "/Users/jaykingchen/PycharmProjects/PINGINGLAB/6.Errors & Exceptions/ArritbuteError.py", line 3, in <module>
b.coun()
AttributeError: 'str' object has no attribute 'coun'
Process finished with exit code 1
异常处理
概述
“建房子”会出现各种问题,如果不对问题进行解决,这个工程就无法完成! 怎么办呢?
异常错误会导致程序中止运行,我们可以对异常进行捕获,进行进一步操作
异常所引发的栈追踪对用户不友好,对于提供给用户使用的软件,异常处理是非常用必要的
异常处理分为异常捕获、异常清理、异常触发几个方面
功能
提高程序健壮性
实现程序的友好度
实现程序的功能调试
异常捕获
try...except...
功能
执行try语句,若没有异常,则正常执行,忽略except代码块
若出现异常,则跳过try语句,执行except代码块
try/except块的工作原理有点像if语句,if语句根据布尔表达式的结果决定如何做,而try/except块根据是否出现了异常决定如何做
举例
例1
捕获一个异常
try:
a = 1
b = 'hello'
print a + b
except TypeError:
try:
a = 1
b = 'hello'
print a + b
except TypeError as e:
print 'except:', e
print 'invalid Type, please try again!'
例2
捕获多个异常,同一处理结果
try:
s = int(raw_input('how old are you:'))
print s
except (TypeError, ValueError):
print 'Please enter an integer value!'
例3
捕获多个异常,不同处理结果
try:
s = int(raw_input('how old are you:'))
print s
except TypeError :
>>> int(1,2)
Traceback (most recent call last):
File "<input>", line 1, in <module>
TypeError: int() can't convert non-string with explicit base
print 'Invalid type,Please enter an integer value!'
except ValueError:
how old are you:hi
Invalid value,Please enter an integer value!
print 'Invalid value,Please enter an integer value!'
例4
捕获所有异常
try:
a = 1
b = 0
print a / b
except :
print 'Error here, please try again!'
例5
捕获异常,与while循环语句结合
def get_age():
while True:
try:
n = int(input('How old are you?'))
return n
except :
print('Please enter an integer value.')
get_age()
例6
捕获异常,与else语句结合
try:
a = 1
b = 2
print a
except TypeError:
print 'invalid Type, please try again!'
else:
若没有异常,则执行else语句
print b
异常清理
try...finally
功能
finally语句用于实现异常清理,不管最终try语句是否有异常,都必须执行finally语句
例如打开一个文件进行操作,不管是否异常,都必须在处理之后将其关闭,通过finally语句可以解决
举例
try:
file1 = open('file.txt','w')
file1.read()
finally:
file1.close()
print 'close the file1'
try...except...finally
功能
finally语句用于实现异常清理,不管最终try语句是否有异常,都必须执行finally语句
例如打开一个文件进行操作,不管是否异常,都必须在处理之后将其关闭,通过finally语句可以解决
举例
try:
file1 = open('file.txt','w')
file1.read()
except IOError:
print 'IOError, please try again!'
finally:
file1.close()
print 'close the file1'
try...except...else...finally
功能
finally语句用于实现异常清理,不管最终try语句是否有异常,都必须执行finally语句
例如打开一个文件进行操作,不管是否异常,都必须在处理之后将其关闭,通过finally语句可以解决
举例
try:
file1 = open('file.txt','w+')
file1.read()
except IOError:
print 'IOError, please try again!'
else:
print 'good!'
finally:
file1.close()
print 'close the file1'
with...as
功能
with类似finally的功能,用于实现程序不管是否异常,都能正常关闭
with 表达式 as 变量
举例
with open('file.txt','w') as f:
不管是否出现异常,通过with语句执行的,最终需要清除
f.read()
异常触发
raise
功能
Raise用于抛出异常,异常可以自己定义
语法
raise [SomeException [, args [, traceback]]]
第一个参数,SomeExcpetion是触发异常的名字
第二个符号为可选的 args(比如参数,值),来传给异常
最后一项参数,traceback,同样是可选的
举例
例1
>>> raise NameError
Traceback (most recent call last):
File "<input>", line 1, in <module>
NameError
>>> raise TypeError
Traceback (most recent call last):
File "<input>", line 1, in <module>
TypeError
>>> raise IndexError
Traceback (most recent call last):
File "<input>", line 1, in <module>
IndexError
例2
def my_number(n):
if n > 0:
raise ValueError, 'invalid number! n = 0 or n < 0'
print 'n: ', n
my_number(1)
例3
def my_number(n):
if n > 0:
raise ValueError, 'invalid number! n = 0 or n < 0'
print 'n: ', n
try:
my_number(1)
except ValueError as e:
print e, 'please try again!'
assert
功能
Assert断言是有条件地触发异常,如果不满足则抛出AssertionError异常
相比raise,多了条件判断;但是不用像raise一样,抛出各种异常类型
语法
assert expression[, arguments]
举例
例1
>>> assert 1 == 1
>>> assert 1 == 2
Traceback (most recent call last):
File "<input>", line 1, in <module>
AssertionError
>>> assert 1 == 2, 'one does not equal two!'
Traceback (most recent call last):
File "<input>", line 1, in <module>
AssertionError: one does not equal two!
例2
try:
assert 1 == 2, 'one does not equal two!'
except AssertionError:
print 'please try again!'
例3
def my_number(n):
assert n > 0, 'invalid number! n = 0 or n < 0'
print 'n: ', n
my_number(10)
my_number(-1)
*主题