Python基础学习
本次Python学习所有操作均以Mac环境为主。
一、安装Python
目前,Python有两个版本,一个是2.x版,一个是3.x版,这两个版本是不兼容的。由于3.x版越来越普及,这里将以最新的Python 3.x版本为基础。
如果Mac系统是OS X>=10.9,那么系统自带的Python版本是2.7。要安装最新的Python 3.x版本,可以通过Homebrew安装,执行以下命令:
brew install python3
在命令行输入 python , 进入到Python交互模式, 输入 exit() 可退出交互模式
此时会发现使用的python还是2.7版本,并没有被覆盖,可以参考https://www.jb51.net/article/116470.htm 进行配置,配置完成后输入python3
python帮助文档:
https://docs.python.org/3.6/tutorial/index.html
https://docs.python.org/3.6/index.html
中文帮助文档
二、变量
如何声明一个变量,直接 变量名 = 值
test = 123 print(test)
其他声明方式:
# 连续赋值声明 a = b = c = d = 123 print(c) # 多个变量多个值,使用 , 隔开 a,b,c = 1,2,3 print(a)
变量的三要素:变量名、变量值、 变量的类型。
变量在使用前都必须先赋值,然后才能使用。
在Python中,变量名必须以字母或下划线字符开头,可以包含字母、数字和下划线。大写字母和小写字母都是允许的。
使用 del 方法,可以删除某个声明过的变量,如需删除多个变量,可用 , 分隔
t = 'asdasd' del t print(t) # 报错 t是未声明变量
变量的作用域:
python变量的作用域一共分为四种:局部作用域(Local) 闭包函数外的函数中(Enclosing) 全局作用域(Global) 内建作用域(Built-in)
在函数体内定义的变量,在外部无法访问。 要在一个函数体内改变某个全局变量,需要使用 global 声明
定义在if 语句、for循环 和 while循环 中的变量,并且这些变量不是定义在函数体内的,变量默认为全局变量
三、运算符
Python运算符包括算术运算符、关系运算符、逻辑运算符、赋值运算符
算术运算符: +(加) -(减) *(乘) /(除) %(取余) //(向下取整) ** (次方)
x = 5 y = 3 a = 4 b = 2 print(x + y) #结果为 7 print(x - y) #结果为2 print(x * y) #结果为15 print(x / y) #结果为1.6666666666666667 不同的机器浮点数的结果可能不同 print(x // y) #向下去整结果为1 print(x % y) #两数相除取余结果为2 print(x**y) #5的3次幂结果为125 print(a / b) #结果为浮点数2.0 print(a % b)#取余结果为0 print(a // b)#取整结果为2
关系运算符: ==(等于) != (不等于) > (大于) < (小于) >=(大于等于)<= (小于等于)
a = 4 b = 2 c = 2 print(a == b) #False print(a != b) #True print(a > b) #True print(a < b) #False print(a >= b) #True print(c <= b) #True
逻辑运算符:and (并且) or (或者) not (非)
a = 4 b = 2 c = 0 print(a>b and b>c) #a>b为True继续计算b>c,b>c也为True则结果为True print(a>b and b<c)#a>b为True继续计算c<b,b>c结果为False则结果为False print(a>b or c<b) #a>b为True则不继续计算c<b,结果为True print(not c<b) #c<b为True not True结果为False print(not a<b) #a<b为False not Flase结果为True
三、数据类型
Python3 中有六个标准的数据类型:Number(数字) String(字符串) List (列表) Tuple (元组) Set (集合) Dictionary (字典)
我们可以使用内置的 type() 函数来查询变量的数据类型
Numberl类型包含 int (整数类型) float (浮点数) bool (布尔类) complex (复数)
bool (布尔类) 是int 的子类,也就是继承了int类型,所以它可以跟进行运算,会默认转为 1 或者 0
print(True + 1) # 输出 2 print(True + 0.1) # 输出 1.1 print(False + 1) # 输出 1
complexf 复数 , 复数 具有实部和虚部两个部分,虚数 是 -1 的平方根的倍数,复数的虚部被表示为 j ,如 c=3.0+1.2j 则c为复数
c = 3 + 1j print(c) #(3+1j) print(c.real) #输出c的实部 3.0 print(c.imag) #输出c的虚部 1.0
在Python 3里,只有一种整数类型 int,表示为长整型,没有 python2 中的 Long。
String类型 用单引号或者双引号括起来
字符串的拼接使用 + ;字符串的拼接必须两个都是字符串;可使用str() 进行类型转换
a = 'hello' b = 'world' c = 123 print(a + b + str(c)) # helloworld123
重复输出同一个字符,使用 *n , n表示重复的次数; 例如重复输出3次 str*3
字符串的截取使用 变量[头下标 : 尾下标] 如果尾下标是负数,表示从末尾的开始位置,比如-1 为倒数第1个字符结束。如果尾下标不写,默认截取到最后一位
a = 'hello' b = 'world' print(a[0]) # h print(a[0:3]) # hel
Python 使用反斜杠(\)转义特殊字符,如果你不想让反斜杠发生转义,可以在字符串前面添加一个 r,表示原始字符串:
print(r'hello \n world') # hello \n world
Python 字符串输出可以使用连续三个单引号、连续三个双引号 、 \符表续行, 也就是完全输出书写的格式(空格全部保留)
print(""" 我是一个程序员 我刚开始学习python""") print('''这是一个 断句''') print('这是一个 \ 断句')
strip() 方法 : 去掉字符串首尾指定的字符
find() 方法: 返回查找字符串中指定字符的下标
rfind() 方法: 从右边开始查找,返回查找字符串中指定字符的下标
replace() 方法: 字符串替换
str1 = ' 两边有空格 ' print(str1.strip())
str1 = '123456789' print(str1.find('5')) # 4
List 列表类型 有序排列的一组数据集合,可用下标索取,如 [1,2,3,4,5,6]
和字符串一样,列表可以连接、重复和被索引和截取,列表的下标是从0 开始的
列表的拼接使用 + 号
a = [1,2,3] b = [4,5,6] print(a + b) # [1, 2, 3, 4, 5, 6]
重复输出一个列表,使用 变量名*n , n表示输出的次数
a = [1,2,3] print(a * 3) # [1, 2, 3, 1, 2, 3, 1, 2, 3]
列表的截取使用 变量[头下标 : 尾下标] 含头不含尾 如果尾下标是负数,表示截取倒数第n个。
a = [0,1,2,3,4,5,6] print(a[0:-5]) # [0, 1] print(a[2:3]) # [2]
关于list的方法:
list.append() : 把一个元素添加到列表的尾部
list.extend() : 把一个列表合并到另一个列表中
list.insert(i , v) : 在列表指定位置插入某个元素,i 表示下标位置
list.remove(x) : 删除列表中值为 x 的第一个元素,不删除后面重复的值,如果没有该元素,返回一个错误
list.pop(i) : 删除列表指定位置的某个元素,如果没有传入下标索引,那么默认删除最后一个元素
list.clear() : 清除某个列表所有的值,变为空列表,相当于 del a[:]
list.index(x) : 返回列表中第一个值为 x 的元素的下标值,如果没有匹配的元素则返回一个错误
list.count(x) : 返回x 在列表中出现的次数
list.sort() : 将一个列表进行正序排序, 列表内的元素必须是统一类型
list.reverse() : 将一个列表进行倒序, 列表内的元素必须是统一类型
list.copy() : 返回一个列表的浅复制,等于 a[:]
将一个列表转换为队列 deque 模块
from collections import deque # 从 collections 包引入 deque 模块 list1 = [1,2,3,4,5] newList = deque(list1) print(newList) # deque([1, 2, 3, 4, 5]) newList.append(6) print(newList) newList.pop() print(newList)
列表的推导式:
list1 = [2,3,4,5] list2 = [34,56,78,90] list3 = [' 这 ', ' 是 ', ' 带 ', ' 空 ', ' 格 '] # 获得一个列表为list1 每个元素的平方 print([x**2 for x in list1]) # [4, 9, 16, 25] # 获得一个列表为list1 每个小于4的元素的平方 print([x**2 for x in list1 if x < 4]) # [4, 9] # 获得一个列表为list1 每个元素的平方,并每个元素独立为一个列表 即二维列表 print([[x**2] for x in list1]) # [[4], [9], [16], [25]] # 获得一个列表为 list1每一项分别与list2每一项相加的值 print([x+y for x in list1 for y in list2]) # [36, 58, 80, 92, 37, 59, 81, 93, 38, 60, 82, 94, 39, 61, 83, 95] # 去掉列表每一项的空格 print([x.strip() for x in list3]) #['这', '是', '带', '空', '格']
Set 集合类型 是一组无序并且不重复的数据,作为一个无序的集合,set不记录元素位置或者插入点。 不存在下标, 如 {1, 2, 3, 4, 5}
如何创建一个集合,可以直接 变量名 = {值,值,... } , 或者使用 set() 方法 ;
一个合集被创建后,会自动去重
一个集合的内部数据位置是随机的, 同个集合每次调用时内部数据的位置都会改变
创建一个空的集合,必须使用 set() 方法 , 因为 变量名 = {} 表示的是一个空的字典
a = {11, 2, 3, 4} b = set("abcdef") # {'e', 'd', 'a', 'c', 'b', 'f'}
可以使用 in 或者 not in 来判断集合中是否存在某个元素 ,返回布尔值
a = {11, 2, 3, 4} b = set("abcdef") print(2 in b) # False print(7 not in a) # True
集合的运算有 差集(-)、并集(|)、交集(&)、对称差集 (^)
差集: a - b 结果等于 如果a合集中某个元素也存在于b合集中,则删除重复的元素, 即把a合集去掉 与b合集重复的元素; 等价于 difference() 方法
a = {1,2, 3, 4} b = {3, 4, 5, 6} print(a - b) # {1, 2} print(b.difference(a)) # {5, 6}
并集 : a | b 结果等于a合集与b合集进行合并; 等价于 union() 方法
a = {1,2, 3, 4} b = {3, 4, 5, 6} print(a | b) # {1, 2, 3, 4, 5, 6}
交集: a & b 结果等于获得同时存在于a合集与b合集的元素;等价于 intersection() 方法
a = {1,2, 3, 4} b = {3, 4, 5, 6} print(a & b) # {3, 4}
对称差集: a ^ b 结果等于a合集与b合集进行合并,并去掉双方都存在的值;等价于 symmetric_difference() 方法
a = {1,2, 3, 4} b = {3, 4, 5, 6} print(a ^ b) # {1, 2, 5, 6}
关于集合的内置函数:
add() 方法: 往set集合中添加一个元素, 注意添加的元素不能为列表或者集合
a = {1,2, 3} a.add("[123]") print(a) # {1, 2, 3, '[123]'}
update() 方法: 往set集合中添加多个元素 添加的元素为列表或者集合,不能只添加一个元素
a = {1,2,3} a.update(["564", 'a']) print(a) # {1, 2, 3, 'a', '564'}
clear() 方法: 清空一个集合所有元素
a = {1,2,3} a.clear() print(a) # set()
copy() 方法: 复制一个集合
a = set('as132456') b = a.copy() print(b) # {'s', 'a', '4', '5', '2', '6', '1', '3'}
remove() 方法: 删除集合中某个指定元素,若删除目标不存在,则会报错
discard() 方法: 删除集合中某个指定元素,不存在也不会报错
a = set('123') a.remove('1') print(a) # {'2', '3'}
pop() 方法: 获得当前集合中的第一个元素
a={1,2,3,4,5,6} print(a.pop()) # 1
len() 方法: 返回当前集合中的元素个数, 也可写成 a.__len__()
a={1,2,3,4,5,6} print(a.__len__()) # 6 print(len(a)) # 6
frozenset()方法: 返回一个冻结的集合,所谓的冻结就是这个集合不能添加或者删除任何元素。该方法的参数必须是一个可迭代的对象,比如列表、集合、元组、字典等
a={1,2,3,4,5,6} frozenset(a) print(frozenset(a)) # frozenset({1, 2, 3, 4, 5, 6})
Tuple 元组类型 跟列表类型类似,不同之处在于元组的元素不能进行修改;用()表示。如 a = (1,2,23,4,('a','b'))
创建一个空的元组,使用 变量名 = () ; 当元组只有一个元素时,需要保留 , 号作为元组的类型区分,如 a = (1 , )
元组中的元素类型可以不同,元素的值也可以是另一个元组,实现元组的嵌套。
访问元组内的元素,使用 元组名[下标值]
元组的截取 使用 元组名[头下标 :尾下标]
元组中的元素值是不允许改变的,不过我们可以对一个元组进行拼接 元组a + 元组b
元组的内置函数:
1、len(tuple):计算元组元素个数。
2、max(tuple):返回元组中元素最大值。 要求元组内的元素是同个类型
3、min(tuple):返回元组中元素最小值。 要求元组内的元素是同个类型
4、tuple(seq):将列表转换为元组。
a = (1,2,23,4,('a','b')) print(len(a)) # 5 print(a[1:-1]) # (2, 23, 4)
dict 字典类型 如 dict1 = {'name': '小明', 'ega': 14}
字典是另一种可变容器模型,且可存储任意类型对象,键必须是唯一的,但值则不必,值可以取任何数据类型,但键必须是不可变的,如字符串,数字或元组。
访问一个字典内部的值,使用 value = 字典名[key]
往字典里面添加一个新的值或者改变一个值, 使用 字典名[key] = value
删除一个字典中某对键值,有三种方法:del 字典名[key] 字典名.pop(key) 字典名.popitem()
dict1 = {'name': '小明', 'ega': 14} del dict1['ega'] print(dict1) # {'name': '小明'}
dict1 = {'name': '小明', 'ega': 14} dict1.pop('ega') print(dict1) # {'name': '小明'}
dict1 = {'name': '小明', 'ega': 14} dict1.popitem() # 随机返回并删除字典中的一对键和值(一般删除末尾对)。 print(dict1) # {'name': '小明'}
关于dict字典的方法:
字典名.pop(key) : 删除字典对应的某对键值
字典名.popitem(): 随机返回并删除字典中的一对键和值(一般删除末尾对)
字典名.clear() : 清空一个字典
字典名.update(字典名): 合并两个字典
字典名.keys() : 获得一个字典所有的键值,返回list 格式
字典名.values() : 获得一个字典所有的值,返回list格式
len(字典名): 获得一个字典的键值个数
str(字典名): 将一个字典转为字符串
dict2 = dict1.copy() : 复制一个字典
key in 字典名:如果键在字典dict里返回true,否则返回false
可更改(mutable)与不可更改(immutable)对象 :
在python中,strings 、tuples、numbers 是不可更改的对象; 而 list 、dict 等则是可以修改的对象
python中的可哈希和不可改变性:
通过help() 方法,包含 __hash__(self, /) 方法的为可哈希对象;
python中所有不可更改的对象都为可哈希对象,如string、tuple、frozenset()
四、条件控制语句
if 判断 if -- elif -- else
python 的 if 判断语句不存在()以及 { } 符号,主要以缩进符的不同区分代码块
#encoding=utf-8 score = input('请输入分数:') if int(score) >= 90: print('优秀') elif int(score) < 90 and int(score) >= 80: print('良好') else: print('一般')
while 循环语句 while -- else 当循环条件不成立的时候执行else
test = 1 while(test < 100): print('循环输出'+ str(test)) test += 1 else: print('循环结束')
for 循环语句 for key in arrar--else else 语句只在for循环正常退出时执行,被强制退出的情况下不执行; 主要用于遍历,除了Number类型,几乎都够使用变量;
list1 = ['小明','小洁','小梦'] for vaule in list1: print(vaule) # 依次输出 小明 小洁 小梦 else: print('循环正常结束') dict1 = {'name':'小明','ega':18, 'height': 100} for key in dict1: print(key) # 依次输出 name ega height for value in dict1.values(): print(value) # 依次输出 小明 18 100
enumerate() 方法: 循环的同时获得下标值
list1 = ['小明','小洁','小梦'] for key, vaule in enumerate(list1): print(key, vaule) # 依次输出 0 小明 1 小洁 2 小梦 else: print('循环正常结束') dict1 = {'name':'小明','ega':18, 'height': 100} for key, value in enumerate(dict1): print(key, value) # 依次输出 0 name 1 ega 2 height
range(a, b, c) 方法: 返回一个数字范围的队列,可传三个参数: a表示序列开始的值,b表示序列结束的值(结束值不包含b), c表示迭代的值(c的值也可以是负数)。 当只传一个参数的时候,a默认为0,c默认为1
for t in range(10): print(t) # 依次输出 0 ~ 9 for n in range(2,10, 1): print(n) # 依次输出 2 ~ 9 for i in range(5,1, -1): print(i) # 依次输出 5 ~ 2
zip() 方法: 配合for 循环使用可同时遍历多个列表
list1 = [2,3,4,5] list2 = [34,56,78,90] for a,b in zip(list1, list2): print(a, b) # 2 34 # 3 56 # 4 78 # 5 90
五、函数 使用 def 创建
pythons使用def 创建一个函数,使用缩进符区分代码块,不存在 {} , 一定要加上 ()
使用return 返回函数内某个值,默认返回None
def test(): print('这是函数逻辑') test()
关于传参:
声明函数时可设置默认参数,默认参数必须写在后面
调用函数并进行传参时,如果使用关键字传参时,可以不按照参数顺序,关键字必须跟形参一致
不定长参数 ,格式为 *变量名, 表示不确定几个参数,它是一个Tuple元组类型 。 在函数内部可以按照传入的顺序进行遍历使用;
def test(name, ega, height = 185): print(str(ega) + '岁的'+ name + '今年身高' + str(height) ) test('小米', 18, 180) # 18岁的小米今年身高180 test(ega = 12, height= 160, name='小洁') #12岁的小洁今年身高160
def test(*v): print(v) # ('小洁', 18, 175) test('小洁', 18, 175)
匿名函数 lambda 用表达式的方式表示一个函数 书写格式为 函数名 = lambda 参数:执行逻辑 , 如果执行的逻辑是计算,会默认 return 计算结果
所谓匿名函数,指的是不再使用 def 语句来定义一个函数
lambda声明的函数传参方式跟 def 定义的函数一致;
test = lambda : print('这是执行逻辑') test2 = lambda value: print(value) test3 = lambda a,b,c: a + b + c test() test2('这是执行逻辑') print(test3(1,2,3)) # 6 默认return
关于函数中的变量:
在函数内部声明的变量,为局部变量,函数外部无法调用。
当函数内的局部变量和全局变量同名时,会默认访问局部变量
函数内部可以调用全局变量,当需要改变全局变量的值时,需要用 global 声明该变量为全局变量
sum = 100 def test(): global sum sum = sum + 1 print(sum) test() # 101
一个函数return出另一个函数,称为闭包;在函数闭包中,当需要改变外层函数变量的值时,需要使用 nonlocal 声明该变量为外层函数变量
def test(): num = 1 def out(): nonlocal num num = num + 1 return num return out print(test()()) # 2
函数的参数传递:
不可变类型:如整数、字符串、元组等作为参数传递时,例如fun(a) ,传递的只是a的值,没有影响a 对象本身。如果在 fun(a) 内部修改 a 的值,只是修改另一个复制的对象,不会影响 a 本身的值
可变类型: 如列表、字典作为参数传递时,例如 fun(list) , 则是将 list 真正传过去, 在fun(list) 内部修改 list 的值, 外部的 list 也会跟着改变。
六、Python的输入和输出
input() 方法: 表示从键盘接收用户输入的一段文本
str1 = input() print(str1)
python 的输入除了转换为字符串进行拼接外,还支持特定字符替换:
%s 表示一个字符串, 支持保留空格, 格式为 %位数s ,默认为左边空格,如果位数是负数,那么默认为右侧空格;
%d 表示一个数字, 支持保留空格, 格式为 %位数d ; ,默认为左边空格,如果位数是负数,那么默认为右侧空格;
%f 表示一个浮点数 支持四舍五入,写法为 %.位数f ; 如保留两位小数位 %2.f
name = '小米' age = 18.8 print('我的名字叫%4s,我今年%-8d岁'%(name,age)) # 我的名字叫 小米,我今年18 岁
format() 方法: 在python的输入中进行字符替换,推荐写法:
保留n位小数,使用 : . nf ;
保留n个空格,使用 : n ; 分别使用 > < ^ 表示左对齐、右对齐、居中
name = '小米' age = 18.888 print('我的名字叫{0:^8},我今年{1:8}岁'.format(name,age)) # 我的名字叫 小米 ,我今年 18.888岁 print('我的名字叫{name},我今年{age:.2f}岁'.format(name=name,age=age)) # 我的名字叫小米,我今年18.89岁
输出格式的转换:
八进制 : :o 十进制 : :d
二进制 : :b 十六进制 : :x 按3位数分隔 : :,
test = 1234657898 print('这是八进制:{:o}'.format(test)) # 这是八进制:15 print('这是八进制:{:b}'.format(test)) # 这是二进制:1101 print(' 按3位分隔:{:,}'.format(test)) # 按3位分隔:1,234,657,898
srt() 方法 和 repr() 方法的区别:
str() 转换输出的字符是给用户看的 , 遇到/n 的时候会进行转译
repr() 转换输出的字符是给解释器看的, 照常输出,不支持转译
七、关于模块
系统模块:
使用import方法导入python的内置模块,导入多个模块可用 逗号 分隔
单独导入某个模块内的某个方法, 格式为 from 模块 import 方法名
查看某个模块下所有的方法,使用 dir() 方法
import math from math import sqrt print(dir(math))
常用的系统模块:
sys 模块:
import sys print(sys.argv) print(sys.path)
os 模块/ math 模块
math.ceil(a) : 求出不小于a的最小整数
math.floor(a) : 求出不大于a的最大整数
import math print(math.ceil(12.34)) # 13 print(math.floor(12.34)) # 12
import random print(random.sample(range(100), 10)) # 随机获得1~99中10个数字组成的列表,不重复 print(random.random())
自定义模块:
可以使用 def 声明一个函数并 return 某个值 作为自定义模块
自定义模块放在当前工作目录下,或者安装python的根目录下,可以使用 import 直接引用 ,使用 sys.path 打印输出的路径都可以放
import sys print(sys.path) #['/Users/zhengweijie/Desktop/pythonTest', '/usr/local/Cellar/python3/3.6.3/Frameworks/Python.framework/Versions/3.6/lib/python36.zip', '/usr/local/Cellar/python3/3.6.3/Frameworks/Python.framework/Versions/3.6/lib/python3.6', '/usr/local/Cellar/python3/3.6.3/Frameworks/Python.framework/Versions/3.6/lib/python3.6/lib-dynload', '/Users/zhengweijie/Library/Python/3.6/lib/python/site-packages', '/usr/local/lib/python3.6/site-packages']
第三方模块:
导入第三方模块之前,需要先下载安装到本地python的安装目录, 使用 pip install 模块名 进行下载
八、包
在创建了很多模块之后,将某些功能相近的文件组织在同一文件夹下,就形成了包;每个包下面必须有一个初始化文件 __init__.py , 该文件可以为空
__init__.py 文件是用于规范 导入模块时使用 * , 文件内容一般为 __all__ = ['模块名',......] , 导入使用 * 时会默认导入 列表中定义的模块
如何导入:
from package import test from package.childer import demo print(test.fun()) print(demo.fun())
九、错误与异常处理
捕获所有的异常类型,使用 except BaseException
import sys try: a = int(input('请输入一个数字')) b = 10/a print(b) except ValueError as e: # 异常类型捕获处理 print('输入数据类型错误') except ZeroDivisionError as e: # 异常类型捕获处理 print('输入数据不能为0') except : # 异常类型捕获处理 print('输入数据不能为0') else: print(sys.exc_info()[0]) # 不知道异常类型的情况下使用,打印出错误类型 finally: print('不管有没有异常都执行')
十、 Python 对文件的处理
文件夹的操作:
os.path.exists(r"路径") : 判断某个文件夹是否存在
os.mkdir(path) : 创建一个文件夹, 不可以重复创建已经存在的文件夹
os.makedirs(path): 创建多个文件夹
import os print(os.path.exists('a')) os.mkdir('a') # 创建 a 文件夹 os.makedirs('e/a') # 创建 e 文件夹 并且里面有个a文件夹
os.walk(path):获得某个文件的信息,这个方法返回的是一个三元Tuple(dirpath, dirnames, filenames), 其中第一个为起始路径,第二个为起始路径下的文件夹,第三个为起始路径下的文件;
dirpath 是一个 string , 代表目录的路径,
dirnames 是一个list , 包含了dirpath 下所有子目录的名字
filenames 是一个list, 包含了非目录文件的名字,这些名字不包含路径信息,如果需要得到全路径,需要使用 os.path.join(dirpath, name)
import os for item in os.walk('/Users/zhengweijie/Desktop/php'): print(item) #('/Users/zhengweijie/Desktop/php', ['.idea'], ['.DS_Store','test.php']) # ('/Users/zhengweijie/Desktop/php/.idea', ['inspectionProfiles'], ['modules.xml', 'php.iml', 'workspace.xml']) # ('/Users/zhengweijie/Desktop/php/.idea/inspectionProfiles', [], [])
os.remove(path) 删除某个文件, 文件不存在报错
os.rmdir(path) 删除空目录
os.removedirs(path) 递归删除空目录, 如 os.removedirs("c\d\f") 如果c d f 都是空目录,会全部删除
import os def deletNotNull (path): fileList = os.listdir(path) # 获得该路径下所有的文件或者文件夹 for t in fileList: # 进行遍历 if os.path.isdir(os.path.join(path, t)): # 如果该文件是文件夹 deletNotNull(os.path.join(path, t)) # 重复调用当前函数,进入下一层文件夹递归删除 else: # 否则是文件,直接删除 os.remove(os.path.join(path,t)) for root, dirs, files in os.walk(path): # 遍历获得该路径下所有文件夹路径 os.removedirs(root)
文件的操作:
使用 open('文件名',mode = '可操作模式') 方法获得一个文件对象, 可传多个参数,默认使用前两个参数 ; 操作完文件后,需要使用 close() 方法关闭文件
mode操作模式取值:
mode="r" 表示只读
mode="rb" 表示读取并转译为二进制 , 可使用 decode('utf-8') 方法转译回中文
mode="w" 表示写入,配合 write() 方法使用, 会覆盖原来的内容 ; 如果原文件不存在,会自动创建一个新文件
mode="a" 表示追加写入,不会覆盖原来的内容,文件不存在则创建一个新的文件
mode="r+" 表示可读可写,会覆盖原来的内容,无法创建不存在的文件
mode="w+" 表示可读可写,如果文件存在,则覆盖文件原来的内容,不存在则创建一个新文件
mode="a+" 表示可读可写,不会覆盖原来的内容,不存在则创建一个新文件
read() 方法 : 读取文件的所有内容
readline() 方法: 读取文件内容的第一行,使用循环可读取出每一行,依次读取
readlines() 方法: 读取文件的所有内容,并将每一行以列表形式返回
files = open('3.txt', mode="rb") text = files.read().decode('utf-8') print(text)
write() 方法: 往文件写入内容
files = open('3.txt', mode="w") files.write('写入内容') files.close()
fell() 方法: 返回文件内容的字节数,一个中文字符占多个字节
files = open('3.txt', mode="w") files.write('我喜欢') print(files.tell()) # 9
seek(offset, what) 方法: 设置文件内容的字节偏移数,即设置光标所在位置; offset 表示偏移数, what 表示偏移位置
seek(x, 0) : 从起始位置即文件首行首字符开始移动X个字符
seek(x, 1) : 从当前位置往后移动 X 个字符
seek(-x, 2) : 从文件的结尾往前移动X 个字符
tell() 方法: 返回文件当前的字符指示位置,理解为光标所在位置
flush() 方法: 刷新文件内部缓冲,刷新文件内容
isatty() 方法: 如果文件连接到一个终端设备返回True , 否则返回False
next() : 方法: 返回文件下一行
truncate([size]): 从文件首行首字符进行截断,截断文件为size 个字符 , 无size 表示从当前位置截断,截断位置之后的所有字符会被删除; windows 下的换行代表2个字符
files = open('text.txt', mode="w+") files.write('这是一个例子') files.seek(0) print(files.read()) files.close()
使用第三方模块 chardet , 可检测文件内容的编码格式,方便使用 decode() 方法进行解码
import chardet files = open('3.txt', mode="rb") text = files.read() print(chardet.detect(text))
递归:
递归的主要表现为自己调用自己,函数内部调用自己的称为递归函数
例子: 计算 1+2+3+4....+n的值
def sum(i): if i == 1: return i else: return sum(i-1)+i print(sum(100))
序列化与反序列化:
序列化是指将对象状态转化为可保持或传输的格式的过程。与序列化相对的是反序列化,它将流转换为对象。这两个过程结合起来,可以轻松的存储和传输数据。
序列化与反序列化的目的:
1、以某种存储形式使自定义对象持久化
2、将对象从一个地方传递到另一个地方
3、使程序更具维护性
序列化:由于存在于内存中的对象都是暂时的,无法长期驻存,为了把对象的状态保持下来,这时需要把对象写入到磁盘或者其他介质中,这个过程就叫做序列化。将变量或者对象通过序列化,转化成字节流存储到文件(磁盘)或者通过网络传输到需要的机器上。因此,我们把变量或对象从内存中变成可存储或传输的过程称之为序列化。
反序列化: 反序列化是序列化的反向操作,把已存在在磁盘或者其他介质中的对象,反序列化(读取)到内存中,以便后续操作,这个过程叫做反序列化。
概括性来说序列化是指将对象实例的状态存储到存储媒体(磁盘或其他介质)的过程。在此过程中,先将对象的公共字段和私有字段以及类的名称(包括类所在的程序集)转换为字节流,然后再把字节流写入数据流。早随后对对象进行反序列化时,将创建出与原对象完全相同的副本。
pickle 模块
pickle.dump(obj, file, [protocol]) : 保存一个对象到指定文件中。 obj表示对象名, file指文件对象, protocol指存储协议,不传默认为0 ASCII协议
pickle.load(file) : 从文件中读取一个对象,并将它重构为原来的Python对象, file指文件对象
import pickle obj = {'name':'小米', 'ega':18, 'height':165} f = open('4.txt', mode="wb") # 一般以二进制形式写入 pickle.dump(obj, f) f.close() f = open('4.txt', mode="rb") newObj = pickle.load(f) print(newObj)
with 语句:with 语句适用于对资源进行访问的场合,确保不管适用过程中是否发生异常都会执行必要的清理操作,释放资源,比如使用文件后自动关闭、线程中锁的自动获取和释放等。
import pickle with open('4.txt', mode="rb") as f: newObj = pickle.load(f) print(newObj)
关于网页爬虫:使用urllib.request
import urllib.request with open('test.txt', mode="wb") as f: f.write(urllib.request.urlopen('https://m.n8n8.cn/gsh/').read())
python 内置函数:
map(规则, 序列) : 表示按照某个规则映射某个序列,即按照某个规则遍历传入的序列,返回一个新的序列 。 这里的传入的规则为某个return函数, 一般跟 lambda匿名函数配合使用
list1 = [1,2,3,4,5,6] print(list(map(lambda x: x*2, list1))) # [2, 4, 6, 8, 10, 12]
id(变量名) : 返回某个变量的内存地址
str(变量名): 转换为字符串类型
int(变量名): 转换为整数类型