Python3教程
前言
本教程主要为Python3教程,但涉及一些Python2语法,文章中默认为Python3,若为Python2则会有标注。
第一章 Python基础
- 缺点:运行速度慢,有速度要求可以用C++改写关键部分;语言不能加密;框架选择太多。
- 注释(5种):单行,多行,批量,中文,特殊注释。
单行注释:#单行注释
多行和批量注释:’’‘多行注释’’’, “”“批量注释”""
中文注释:#coding=utf-8,需放在第一行。或#--coding:utf-8 --;
特殊注释:主要应用于linux系统,用来告诉Python解释器的位置。用法:#!/usr/bin/env python - 标识符:区分大小写;字母,数字,下划线组成,不能以数字开头;以双下划线开头或结尾的表示特殊含义
- 变量:弱变量类型,分号或换行表示结束,命令行的print可以省略
通常声明和赋值:变量名=字面量或表达式
链式赋值:变量1=变量2=字面量或表达式
复合赋值运算符(简洁表达式):+=,-=,*=,/=,//=(整除)
删除变量:del+变量名 - 解包操作:变量1,变量2,……=字面量或表达式1,字面量或表达式2……
类型可以不一样,因为是弱变量类型语言 - 行与缩进
python最具特色的就是使用缩进来表示代码块,不需要使用大括号 {} 。
缩进的空格数是可变的,但是同一个代码块的语句必须包含相同的缩进空格数。 - 基础语法
1) print语句
i. 基础用法
print 默认输出是换行的,如果要实现不换行需要在变量末尾加上 end="":
实例:
x=“a”
y=“b”
# 换行输出
print( x )
print( y )
print(’---------’)
# 不换行输出
print( x, end=" " )
print( y, end=" " )
print()
ii. 高级用法
print(‘str1=%s\nstr2=%s\ndata=%.2f’ % (str1, str2, data)) #%s为字符串,%f为浮点数,%.2f表示小数点精确至2位(默认是6位)
print(‘str1=’, str1, ‘data=’, data) #拼接
print(‘a’*5) #循环
print((‘a’*5).center(50)) #50表示居中的长度
第二章 数据类型
- 数据类型:
分为两大类:内置数据类型,自定义数据类型
内置数据类型:数值,序列,集合,字典,特殊,其他数据类型
数值数据类型:整数,浮点数,布尔,复数
序列数据类型:字符串,元祖,字节序列,列表,字节数组
集合数据类型:集,不可变集 - 查看类型:type(x)
>>> f=3.14
>>> type(f)
<class ‘float’> - 整数数据类型(int):
十六进制:0x+数字;例:0xa 即10
十进制:
八进制:0o
二进制:0b
int对象:int(x) ;int(x, y) 例:a=int(‘100’, 2) 则a=4 - 字符和字符串不区分单引号和双引号
- 浮点数(float)
没有单精度和双精度之分
小数点前面的前导0可以省略,如num= .4
float对象:float(x) - 复数
用 j 表示:例1+1j,不能写1+j
complex对象:complex(x, y) 例:c=complex(4, 3),则c=4+3j。虚部为0可省略不写,即complex(4)或complex(4, )均为4+0j。 - real:复数的实部。例:(1.2+3.4j).real=1.2
- imag:复数的虚部。用法同上。
- 布尔类型(bool)
True或False首字母要大写
bool对象:bool(x),非零一律为真。0,00,‘0’,0.0 都是False
第三章 字符串
- 字符串的表现形式有4种
’ ‘:表示一行
" " :表示一行
‘’’ ‘’’:可以跨行
“”" “”":可以跨行 - 字符串拼接:
>>> ‘abc’+‘def’
‘abcdef’
>>> ‘abc’‘def’
‘abcdef’
>>> a=abc - 转义字符:需放在print语句里;字符串前加上r或R,则不会有转义作用,作用同\(即原始字符串)
转义字符及其含义:
\n 换行
\r 回车
\t 一个水平制表符
\v 一个垂直制表符
\’ 单引号
\" 双引号
\ 反斜杠符号
\b 退格
\f 换页 - 类型转换:自动转换
- 显性类型转换(慎用):能用隐性则不用显性,容易精度丢失
例:float(i)
第四章 运算符
- 算术运算符:+,-,*,/,//,%,**
- 赋值运算符:=,+=,-=,*=,/=,%=,**=,//=
- 位运算符:&,|,^,~,<<左位移,>>
- 逻辑运算符:and, or, not;可以用数值表示
- 成员运算符:in,not in;判断一个元素是否在另外一个元素中。
- 身份运算符:is ,is not;用来比较2个对象的存储单元。存储单元在一个位置则True。
- 括号运算符:改变优先级顺序。
- 运算符的优先级
- 语法错误:print(x+y),不表示拼接,表示x与y相加。
正确方法:print(x, y),x与y用空格隔开,表示拼接。
第五章 流程控制语句
- 分为顺序语句,判断语句(选择语句),循环语句,没有开关语句
- 顺序语句:略
- 判断语句:
1)条件表达式:
关系,逻辑,算术表达式
2)语句:
单个语句,或多个语句,多个语句需要注意缩进(因为没有花括号)
3)单分支:
if(条件表达式):
语句
4)多分支:
if():
语句
else:
语句
或
if():
语句
elif():
语句
……
else:
语句 - 循环语句:for和while循环
1) 可迭代对象:
系列、字典、文件对象、迭代器对象、生成器对象
2) 迭代器对象:
range对象:用来产生指定该对象的数字序列
range(start, stop, [step]);不包含stop;step为1时可以省略,star为0时可以省略
在python2中,range是一个函数,为生成器。
3) for循环:
for 变量 in 对象集合 :
语句
4) 示例:
for i in range(1, 11, 1) :
print(i, end=’ ’ )
5) sum_odd=0
sum_even=0
for i in range(1, 101) :
if (i%2 !=0) :
sum_odd += i
else :
sum_even += i
print(‘1-100的奇数之和为’, sum_odd)
print(‘1-100的偶数之和为’, sum_even)
6) while循环
while (判断条件) :
语句
7) 循环else字句:
如果循环没有被break终止,则会执行else
while 判断条件 :
语句
else :
语句
8) 循环的嵌套
for i in range(1, 10) :
for j in range(1, 10) :
print(i, ‘’, j, ‘=’, ij, end=’\t’)
9) 循环的其他语句
i. break:可以跳出 for 和 while 的循环体。如果你从 for 或 while 循环中终止,任何对应的循环 else 块将不执行。
示例:
if var == 5:
break
ii. continue:用来告诉Python跳过当前循环块中的剩余语句,然后继续进行下一轮循环。
示例:
if var == 5: # 变量为 5 时跳过输出
continue
10) 死循环
ctrl+C:终止当前运行的程序
11) 空语句
pass语句,表示一个空的代码块
第六章 数据结构-容器
- 数据结构:在Python中,常见的数据结构成为容器
序列(列表,元组),映射(字典),集合是三类主要的容器 - 数组:用来储存和处理大量数据,数组通过索引下标进行访问
Python中没有数组,可以使用序列数据类型来表示数组
6.1 序列
- 序列数据类型
序列数据类型是Python语言中最基本的数据结构,是一组有顺序的元素的集合。序列数据可以包含一个或多个元素,也可以是空序列(没有任何数据)
序列数据类型包括:元组,列表,字符串,字节数据 - 序列:把大量的数据按次序排序而形成的集合称为序列,在Python中,字符串,列表和元组都是序列
在Python中,所有的序列类型都可以进行某些特定的操作,这些操作包括索引,分片,加,乘,以及检查某个元素是否是某个序列的成员,序列的长度,最大元素,最小元素,等等 - 列表:
列表的创建方式:字面量,对象,推导式
1) 字面量
list = [1, 2, 3, 4, 5, 6]
list = [1, 2, ‘a’, 3]
list = [[1, 2, 3], [4, 5, 6]] #二维列表
list = [1, 2, 3, [1,2,3]]
2) 对象
list = list() #空列表
list(‘abcd’) #迭代对象
list(range(3))
3) 推导式
用非常简单的表达式满足特定的列表
表达式 for 变量 in 序列
list = [xx for x in range(1, 10)]
list = [2x for x in [1, 2, 3]]
list = [i for i in list2 if i%2 == 0] - 列表的操作
包括:长度,最大值,最小值,求和
1) 访问列表:list[下标]
2) 更新列表:list[下标] = 新值
3) 删除列表中的元素:del 列表[下标]
4) 追加元素:list.append(obj) #obj为对象
5) 插入元素:list.insert(index, obj) #index为下标
6) 求长度,最大值,最小值,求和
len(list)
max(list) #最大值,最小值必须满足列表元素数据类型一致
min(list)
sum(list) #求和需要列表元素均为数值
7) 切片:截取列表的一部分
s[i: j] #i为起始下标,j为终止下标;前包后不包(括);下标可以为负数,负数表示从末尾倒数,若下标超出边界,不会报错;i可省略,但冒号不能省略。
s[i: j: k] #k为步长,可以省略
8) 连接和重复
连接:+ +=
重复:* *=
list1 + list2
3 * list1
list1 += list2
9) 成员关系操作:判断一个元素是否在列表当中
in
not in
count(元素) : 元素在列表中出现的次数。用法 list.count(元素)
index(): 指定元素在列表中第一次出现的下标
用法:list.index(x, i, j) #i和j为下标范围,x不存在会报错
10) 比较运算操作:<, <=, >, >=, !=, ==
元素逐个进行比较,以第一个差别出现为准
11) 排序:sorted(),不改变原列表的顺序
sorted(list)
12) 内置函数:any(list), all(list)
判断列表的元素是否全部都为True
any存在True则为True,all所以True才为True
13) 列表的遍历
示例1:
for i in list:
print(i)
示例2:
for i in list:
print(‘序号:%s 值:%s’ %(list.index(i)+1, i))
示例3:
for i in list:
print(‘序号:%s 值:%s’ %(i+1, list[i] ) )
14) 列表的拆封
a, b = [1, 2] #个数必须是一致的
高级拆封
data = [1, 2 ,3]
a, b, c = data - 元组:它是一个定值表,用来储存不变的值,没有括号也可以,元组可以嵌套
t=(‘abc’, ‘de’, 123, 45)
t=1, 2, 3
对象创建方式:只能有1个值
t=tuple(‘abc’) 为(‘a’, ‘b’, ‘c’)
t=tuple([1, 2,3])
t=tuple(range(8))
方法5:
u=tuple(‘abc’)
v=u, (1, 2, 3)
则v=((‘a’, ‘b’, ‘c’), (1, 2, 3) ) - 元组的操作:索引访问,切片,链接,重复,成员关系,长度,最大值,最小值,输出,等等
1) 基础操作同列表
2) 元组的遍历
for x in t:
print(x, end=’ ')
排序输出:
sorted(t) 输出为列表,但不改变原元组
3) 元组的拆分
i. a, b=(1, 2)
ii. data=(1001, ‘张三’, (100, 89, 90))
sid, name, scores=data
iii. first, *middle, last=(1, 2, 3, 4, 5) 则middle为[2, 3, 4]
或first, middle, *last=(1,2,3,4,5)则last为[3,4,5]
iv. 临时拆分:
_, b, _ = (1, 2, 3)
则b=2, _ =3
4) 元组与列表相互转换
t1=(1,2,3,4)
list1=list(t1) 反之相同
6.2 字典-映射
- 字典的创建方式
i. 字面量
{键1: 值1, 键2: 值2, 键3: 值3} #冒号可以用=代替
{}为空值
ii. 对象:
dict()创建,需要使用列表或元组
dict3=dict( [ [‘优’, 90], [‘良’, 80] ] )
或dict3=dict( ( (‘优’, 90), (‘良’, 80) ) )
或dict3=dict(zip([‘优’, ‘良’], [90, 80]))
iii. fromkeys函数:
值是统一的值,不写为空值
dict4={}.fromkeys([‘优’, ‘良’], ‘大于60分’)
dict5={}.fromkeys([ ]) 或 ([ ], None) 为空值
iv. 推导式:
{键: 值 for}
dict6={n: n**2 for n in range(1, 5)} - 字典的操作
i. 访问:
1) dict名[键],例:dict2[‘良’]
2) dict名.get(键, 提示信息) #提示信息可以不写
例:dict2.get(‘优’) 或 dict2.get(‘优’, ‘键不存在’)
3) 获取所有键值对,键,值
dict3.items(), dict3.keys(), dict3.values()
或 for i in dict3: #键
print(i, end=’, ‘)
for i in dict3.items(): #键值对
print(i, end=’, ')
ii. 添加或修改
dict2[‘a’]=‘apple’ #没有则添加,有则修改
iii. 合并
dict1.update(dict2) #如果键重复,则更新(即覆盖)
iv. 删除
del()函数:删除一对键值 del(dict2[‘优’])
del语句:删除整个字典 del(dict2)
pop(): dict1.pop(‘No2’, ‘键不存在’) 先输出再删除
popitem() 随机删除
clear():清空字典中所有元素
6.3 集合
可变集合(set),不可变集合(frozenset),没有重复和顺序,集合可以相互比较
- 创建:
i. 字面量:{1, 2, 3, 4, 2, 4}
ii. 对象创建:set(‘hello’)
set2=set((1,2,3,4,5)) 或 列表格式
set5=frozenset(‘hello’)
iii. 推导式
{x*x for x in range(1, 5)} - 遍历
for i in set1:
print(i, end = ', ') - 运算
| 并集,&交集,- 差集,^ 对称差集 - 操作:
i. 最大值,长度等
ii. 合并:set3.update(set4)
iii. 复制:set2=set1.copy() #前拷贝
6.4 字符串2
- 操作:同列表,字典等
len(str1)
str1(3:)
3*str1
max(str1)
str1==str2 - 编码问题
str=‘字符串str编码和解码操作’
b1=str.encode(encoding=‘cp936’) #默认是utf-8
b1.decode(encoding=‘cp936’) - %f:浮点数,%s字符串
‘结果为%f’ %88 - print( (’*’*5).center(50) ) #长度为50,并居中
第七章 函数
函数的声明和创建:def语句
def 函数名 (参数列表):
语句 | 函数体
示例:
def my_average(a, b):
return (a+b)/2
第八章 类与对象
- 前言:
封装:面向对象的主要特征
多态:派生类具有基类所有非私有数据和行为以及新类自己定义的所有其他数据或行为,即子类拥有2个数据类型。多态允许每个对象以自己的方式去响应共同的消息。 - 类的创建
class 类名:
类体 - 对象的创建
对象名=类名(参数列表)
对象.属性
对象.方法
java中:
python中:class Person{ String name; int age; public Person(String n, int a){ this.name=n; this.age=a; } }
class Person: def __init__(self, name, age): self.name=name self.age=age def say_hi(self): print('你好,我叫', self.name) p1=Person('张三', 45) p1.say_hi()
- 可以无参无内容(类放在全局中,可以用类名调用)
class Person:
pass
或无参有内容
class Person:
count=0
name = ‘大连理工大学’
p3=Person()
p3.name
Person.count +=1
Person.count - 函数和方法的区分
参数中有self的是方法,没有的为函数 - 封装:
i. 属性:
私有属性:在熟悉名前加2个下划线
ii. 自定义属性:即增加属性,只能是公开属性class Car: name='aodi' __price=100 类内函数 c1=Car() # 则c1不能访问c1.__price,若想访问,则需类内定义函数 # 方法一: def get_into(): print(Car.__price) Car.get_into #使用全局调用 # 方法二: # 调用私有属性:对象._类名__私有属性 c1._Car__price # 方法三:装饰器@property(属性) class Person: def __init__(self, name): self.__name=name @property # 提供只读属性 def name(self): return self.__name p=Person('Tom') print(p.name) # 方法四:getter, setter class Person: def __init__(self, name): self.__name = name @property def name(self): return self.__name @name.setter def name(self, value): self.__name = value @name.getter def name(self): return self.__name p= Person('Tom') p.name = 'allen' print(p.name) # 方法五:人工构造 class Person: def __init__(self, name): self.__name=name def getname(self): return self.__name def setname(self, value): self.__name=value def delname(self): del self.__name name = property(getname, setname, delname, '我是name属性') p=Person('Tom') p.name='Allen'
iii. 自动获取属性class C1: pass o = C1() o.name = '自定义属性' print(o.name) o.__dict__
iv. 方法:class Person: def __init__(self): pass def __getattribute__(self, name): return str.upper(object.__getattribute__(self, name)) def __setattribute__(self, name, value): object.__setattr__(self.name, str.strip(value)) o=Person() o.firstname='DLUT' print(o.firstname)
v. 私有方法# 示例方法:def 方法名(self, [参数列表]) class Person: def say_hi(self, name): self.name=name print('我叫', self.name) p=Person() p.say_hi('软件学院') # 静态方法: @staticmethod def 方法名称([参数列表]) class Person: @staticmethod def show(name): return name+1 Person.show(1) # 类方法: @classmethod def 方法名称(cls, [参数列表]) class Foo: classname = 'Foo' def __init__(self, name): self.name=name def f1(self): print(self.name) @staticmethod def f2(): print('static') @classmethod def f3(cls): print(cls.classname) f = Foo('中') f.f1() Foo.f2() Foo.f3()
class Methods: def publicMethod(self): print('公有方法') def __privateMethod(self): print('私有方法') def publicMethod2(self): self.__privateMethod() m=Methods() m.publicMethod() m.__privateMethod() #不能访问 m._Methods__privateMethod() Methods.publicMethod(m) #需传参,参数需为对象
- 方法重载:方法名相同,参数的个数不同;但最后的函数会覆盖前面的函数,所以有些书认为没有方法重载
class Person: def say_hi(self, name): print('你好,我叫', self.name) def say_hi(self, name, age): print('你好,我叫{0},我的年龄是{1}'.format(name, age)) p=Person() p.say_hi('tom', 23)
- 继承
一个类的父类可以有多个
class 派生类(基类1, 基类2, …):
示例;class Foo(object): #object可默认不写 class Persion: def __init__(self, name, age): self.name = name self.age = age def say_hi(self): print('你好,我叫{0},年龄{1}'.format(self.name, self.age)) class Student(Person): def __init__(self, name, age, stu_id): Person.__init__(self, name, age) self.stu_id = stu_id def say_hallo(self): Person.say_hi(self) print('我是学生,我的学号是', self.stu_id, sep='') p1 = Person('张三', 33) p1.say_hi() s1 = Student('李四', 19, '20181010') s1.say_hello() # 只有一个父类时,可以用super代替父类的类名,super会自动查找 class Student(Person): def __init__(self, name, age, stu_id): super(Student, self).__init__(name, age) self.stu_id = stu_id def say_hello(self): super(Student, self).say_hi() print('我是学生,我的学号是', self.stu_id) s1 = Student('Allen', 23, '20190101') s1.say_hello()
- 查看层次关系
mro()或__mro__
示例:class A: pass class B(A): pass class C(B): pass class D(A): pass class E(B, D): pass D.mro() E.__mro__ class Dimesion: def __init__(self, x, y): self.x = x self.y = y def area(self): pass class Circle(Dimesion): def __init__(self, r): Dimesion.__init__(self, r, 0) def area(self): return 3.14*self.x*self.x class Rectangle(Dimesion): def __init__(self, w, h): Dimesion.__init__(self, w, h) def area(self): return self.x * self.y d1 = Circle(2.0) print(d1.area()) # 调用的是非私有的方法,如果子类方法是私有,则会出现None
- 运算符的重载(重写特殊方法)
方法名字要用__开头__结尾
使用:class Person: def __init__(self, name, age): self.name = name self.age = age def __str__(self): return '{0}, {1}'.format(self.name, self.age) p = Person('Tom', 23) print(p) x = 1 y = 2 print(x+y) x.__add__(y) def __add__(self) return
第九章 文件与流
- 文件的分类采用的根据编码的方式,分为两大类:文本的文件(ASCLL码组成),二进制文件
- 文件相关的模块:
IO模块:文件流的输入输出操作模块
bz2模块:压缩算法导入,即读取和写入基于bz2的压缩算法
gzip模块:同上,gzip压缩算法
zipfile模块:同上
zlib模块:同上
tarfile模块:读取和写入tar格式的卷文件 - 正则操作,爬虫方面模块
glob模块:查找符合特地规则的文件路径名
fnmatch模块:使用模式来匹配文件路径名
fileinput:处理一个或多个输入文件
filecmp:用于文件的比较
csv:读取和写入csv格式的文件
pickle和cpickle:序列号对象
xml包:处理xml文件
os模块:处理文件 - 文本文件的操作:
1) 打开文件open(file, read/write)
open
write
writelines
close()
2) 操作
read() 全部读完
readlines() 全部读取,每一行组成列表
readline() 读取一行
3) 关闭
4) with语句:自动生成,打开并关闭资源
with open(路径, 模式) as f:
示例:with open(r'd:\data.txt', 'w', encoding='utf-8') as f: # r代表禁止转移字符 f.write('123\n') f.write('abc\n') f.writelines(['456\n', 'def\n']) with open(r'd:\data.txt', 'r', encoding='utf-8') as f: for s in f.readlines(): print(s, end=' ') # 二进制文件的读写 with open(r'path', 'wb') as f: f.write(b'abc') with open(r'path', 'rb') as f: b = f.read() print(b) # 随机文件读取,模式改为'w+b' # 内存文件的操作:在内存中创建临时文件,进行数据的读取和写入,需要用io模块,在模块中,StringIO和GytesIO对象来实现内存操作 from io import StringIO f = StringIO('hello\nhi\ngoodbye') for s in f: print(s) from io import BytesIO f = BytesIO() f.write('abc'.encode('utf-8')) f.seek(0) b=f.read() print(b) print(f.getvalue())
- 压缩
import sys, gzip filename = sys.argv[0] filenamezip = filename + '.gz' with gzip.open(filenamezip, 'wt') as f: for s in open(filename, 'r'): f.write(s) for s in gzip.open(filenamezip, 'r'): print(s)
- csv操作:逗号分隔符文本格式,常用于excel或数据库的导入和导出操作
import csv def readcsv1(csvfilepath): with open(csvfilepath, newline=' ') as f: f_csv = csv.reader(f) # 创建csv.reader对象 headers = next(f_csv) # 标题 print(headers) for row in f_csv: print(row) if __name__=='__main__': readcsv1(r'd:\scores.csv') # 示例2 import csv def writecsv1(csvilepath): headers=['StuID', 'Name', 'Sex', 'Class', 'Math', 'Chinese', 'English'] rows=[('20181010', 'Allen', 'Male', 'Class1', '90', '80', '78'), ('20181011', 'Mary', 'Female', 'Class2', '90', '98', '92')] with open(csvfilepath, 'w', newline=' ')as f: f_csv=csv.writer(f) f_csv.writerow(headers) f_csv.writerows(rows) if __name__='__main__': writecsv1(r'd:/sc.csv')
第十章 os模块
- path属性:路径
exists(): 是否存在
remove(): 删除文件
示例import os filename = r'd: \data1.txt' isExists = os.path.exists(filename) if isExists: os.remove(filename) print('文件删除成功') else: print('要删除的文件不存在')
- 创建和删除文件夹
mkdir(): 创建一个文件夹
makedirs(): 创建多级文件夹
示例import os dirname = r'd:\pythontest' multipledirname = r'd:\pythontest1\program\test' isExists = os.path.exists(dirname) if isExists: print(dirname, '文件夹已经存在了') else: os.mkdir(dirname) print('成功创建了文件夹', dirname) isExists = os.path.exists(multipledirname) if isExists: print(multipledirname, '文件夹已经存在了') else: os.mkdir(multipledirname) print('成功创建了多级文件夹', multipledirname)
- 删除文件夹
rmdir(): 只能删除空文件夹
如果想删除整个文件夹,不管里面是否为空,则需要使用shutil对象中的rmtree()函数import os import shutil dirname = r'd:\pythontest' # multipledirname = r'd:\pythontest1\program\test' multipledirname = r'd:\pythontest1' isExists = os.path.exists(dirname) if isExists: os.rmdir(dirname) print('成功删除文件夹') else: print('要删除的文件夹不存在') isExists = os.path.exists(multipledirname) if isExists: # os.rmdir(multipledirname) shutil.rmtree(multipledirname) print('成功删除文件夹') else: print('要删除的文件夹不存在')
- import os, sys
def genDir():
base = r’d:/bd/train/train1/’ # 多级文件夹时尽量用正斜杠,’/’,否则会报错i = 1 for j in range(100): file_name = base + str(i) os.mkdir(file_name) i = i+1 if __name__=='__main__': genDir()
- listdir(): 返回指定目录下的所有文件和文件夹
import os, sys path1 = r'c:/101test' path2 = r'd:/bd/train/train/train1/' def MKDir(): dirs = os.listdir(path1) for i in dirs: file_name = path2+str(i) os.mkdir(file_name) if __name__=='__main__': MKDir()
- 从文件中读取文件夹名字,并创建
import os basepath=r'd:/bd/train/train1/' for line in open(r'c:/102test/ab.txt'): basename = line.strip() #去掉前后的空格 folder = os.path.join(basepath, basename) # 将列表组成字符串 filename = os.path.join(folder, basename) os.mkdir(folder) open(filename, 'w').close()
- 对象序列化(串行化)
import pickle with open(r'd:/pythontest1/dataObj.dat', 'wb') as f: s1 = 'hello' s2 = 1+2j s3 = (1, 2, 3) s4 = dict(name='Mary', age=19) pickle.dump(s1, f) pickle.dump(s2, f) pickle.dump(s3, f) pickle.dump(s4, f) # 反序列化 import pickle with open(r'd:/python')as f: o1=pickle.load(f) o2=pickle.load(f) o3=pickle.load(f) o4=pickle.load(f) print(type(o1), str(o1)) print(type(o2), str(o1)) print(type(o3), str(o1)) print(type(o4), str(o1))
第十一章 异常-错误
- 错误类型(三种):语法,运行时,逻辑错误
1) 语法错误:拼写错误。
2) 运行时错误:在解释执行过程中产生的错误,如:导包过程没有执行,文件不存在
3) 逻辑错误:程序可以运行,但是执行结果不正确,即编译器无法检查出来 - 异常定义:
try: 定义的代码块
except: 捕获特定的异常并执行相应的操作
finally: 不管是否发生异常,都会执行
例:
def readline()
try:
可能产生的错误
except FileNotFoundError: # 只能写一个异常,但可以有多个except语句
except PermissionError: - 继承关系:子类放在前面写,父类放在后面写
BaseException #最大的
SystemExit
Exception
KeyboardInterrupt
Generator - 常见的类
NameError: 尝试访问一个没有声明的变量
SyntaxError: 语法错误
AttributeError: 访问未知对象的属性
TypeError: 类型错误
ValueError: 数值错误
ZeroDivisionError: 零除错误
IndexError: 索引越界
KeyError: 字典关键字不存在 - 示例:
try: f = open(r'test.txt', 'w') f.write('This is a test file.') f1. = open('resxtifile.txt', 'r') except IOError: print('Not found the file') else: # 没有异常时,执行的语句 print('File writing success!') finally: f.close()
- 自定义异常
一般都要继承Exception或其子类
示例:class NumberError(Exception): def __init__(self, data): Exception.__init__(self, data) self.data = data def __str__(self): return self.data+'非法数值' def total(data): total = 0 for i in data: if i<0: raise NumberError(str(i)) total=total+1 return total
第十二章 断言
断言是做调试用的
- 前置条件断言
- 后置条件断言
- 前后不变断言
- assert 布尔类型的表达 | 结果为布尔类型的函数
- assert 布尔类型的表达式,字符串表达式
- python解释器的两种运行模式:调试模式,优化模式。通常为调试模式,内置只读变量__debug__为True。使用选项 -O 运行时(即cmd中,命令为python -O file.py),模式变为优化模式,此时__debug__为Flase。
if __debug__: if not testexpression: raise AssertionError if __debug__: if not testexpression: raise AssertionError(data) # 示例: a = int(input('请输入整数A')) b = int(input('请输入整数B')) assert b!=0, '除数不能为0' c = a/b print(c)
- 改进方案
使用专门的开源的测试框架来进行测试操作''' 1) py.test: 它是一个轻量级的测试框架 pip install -U pytest 运行(在命令行中): py.test 文件名.py ''' # 2) 使用Python自带的测试框架unittest import unittest class TestStringMethods(unittest.TestCase): def test_upper(self): self.assertEqual('foo'.upper(), 'Fo0') if __name__=='__main__': unittest.main() # 3) ptest # Karl大神,可读性非常好 from ptest.decorator import * from prest.assertion import * @TestClass() class TestCase: @Test() def test1(self): actual='foo' expected='bar' assert_that(expected).is_equal_to(actual) # 4) assertpy包 from assertpy import assert_that def test_something(): assert_that(1+2).is_equal_to(333) assert_that('foobar').is_length(6).starts_with('foo').ends_with('bar') if __name__=='__main__': test_something() # 5) 17个方法,可以在网上查阅
第十三章 数据库
- 数据库定义:存储数据的仓库。存储在计算机系统中结构化的,可共享的相关数据仓库,在数据库中,数据是按照数据模型进行组织、描述和存储的,可以最大限度的减少数据的冗余度
- DBMS(数据库系统):用于管理和操作数据库的计算机软件,可以用于数据的定义和检索
- DDL,DML
- DBMS的分类
适用于企业用户的网络版:Oracle,sql server,IB2,MySQL
适用于个人用户的桌面板:Access,MySQL 5.0 - 数据库的模型:关系型,层次型,网状型,面向对象型
关系型:实体和联系
数据库中的实体:表,视图,序列
联系的分类,一对一,一对多,多对多 - 表中的行(记录或元组)和列(字段)
约束 - 通用数据库访问模块
ODBC
ODBC Interface
pyodbc
mxODBC: 开源收费
JDNC - Nabicat 9 Lite for MySQL #MySQL的图形化界面
- 创建表
import pymysql db=pymysql.connect("localhost", "root", "root", "testdb") cursor=db.cursor() cursor.execute("DROP TABLE IF EXISTS employee") # 使用预处理的方式进行建表 sql="""CREAT TABLE employee( first_name CHAR(20) NOT NULL, last_name CHAR(20), age INT, sex CHAR(1), imcome FLOAT)""" cursor.execute(sql) db.close()
- 将csv文件导入到MySQL数据库:
# 11.csv为csv文件,导入时需要先在数据库创建表 import pymysql import csv import codecs def get_conn(): conn = pymysql.connect( host='localhost', port=3306 user='root' passwd='root' db='test_csv' charset='utf8' ) return conn def insert(cur, sql, args): cur.execute(sql, args) def read_csv_to_mysql(filename): with codecs.open(filename=filename, mode='r', encoding='utf-8') as f: reader=csv.reader(f) head=next(reader) conn=get_conn() cur=conn.cursor() sql='insert into tb_csv values(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)' # 简写 for item in reader: if item[1] is None or item[1]=='': continue args=tuple(item) print(args) insert(sur, aql=sql, args=args) conn.commit() # 提交和关闭不能忘 cur.close() conn.close() if __name__=='__main__': read_csv_to_mysql(r'd:/11.csv')
- 将数据库数据写入到csv文件
import pymysql import csv import codecs def get_conn(): conn = pymysql.connect( host='localhost', port=3306 user='root' passwd='root' db='test_csv' charset='utf8' ) return conn def query_all(cur, sql, args): # args可以不写 cur.execute(sql, args) return cur.fechall() def read_mysql_to_csv(filename): with codecs.open(filename=filename, mode='w', encoding='utf-8') as f: write=csv.writer(f, dialect='excle') conn=get_conn() cur=cunn.cursor() sql='select * from tb_csv' # '*' 尽量不要写 results=quer_all(cur=cur, sql=sql, args=None) for result in results: print(result) write-weiterew(result) if __name__=='__main__': read_mysql_to_csv(r'd:/22.csv')
- 项目实战
# 1) pandas: 数据分析库 # 安装:pip install pandas import pymysql # 字典模式 config=dict(host='localhost', user='root', password='root', xursorclass=pymyaql.cursors.DictCursor ) # 建立连接 conn=pymysql.connect(**config) # 自动提交 conn.autocommit(1) # 设置光标 cusor=conn.cursor() import pandas as pd df=pd.read_csv(r'd:/33.csv', encoding='gbk', usecols[0, 3, 4, 5, 6, 11], parse_dates=['日期']) print(df.head()) def make_table_sql(df): columns=df.columns.tolist() types=df.ftypes mak_table=[] for item in columns: if 'int' in types[item]: char=item+' INT' elif 'float' in types[item]: char=item+' FLOAT' elif 'object' in types[item]: char=item+' VARVHAR(255)' elif 'datetime' in types[item]: char=item+' DATETIME' make_table.append(char) return ','.join(make_table) # csv格式输入到mysql中 def csv2mysql(db_name, table_name, df): # 创建数据库 cursor.execute('CREAT DATABASE IF NOT EXISTS {}'.format(db_name)) # 连接 conn.select_db(db_name) # 创建表 cursor.execute('CREAT TABLE {}'.format(table_name, make_table_aql(df))) df['日期']=df['日期'].astype('str') values=df.values.tolist() s=','.join(['%s' for _ in range(len(df.columns))]) cursor.excutemany('INSERT INTO {} VALUES([])'.format(table_name, s), values) cursor.close() conn.close() if __name__=='__main__': csv2mysql('stock', 'test1', df) # 2) sqlalchemy import pandas as pd from sqlalchemy import create_engine from datetime import datetime from sqlalchemy.types import NVARCHAR, Float, Integer engine=create_engine("mysql+pymysql://root:root@127.0.0.1:3306/stock?charset=utf-8", max_overflow=5) # 密码相同可不写,最大连接数为5 con=engine.connect() df=pd.read_csv(r'd:/33.csv', encoding='gbk', usecols=[0, 3, 4, 5, 6, 11],parse_date='日期') def map_types(df): dtypedict={} for I, j in zip(df.columns, df,dtypes): if "object" in str(j): dtypedict.update({i:NVARCHAR(length=255)})