python学习第三个坑
##########################python 第三章 ################################
这一章呢,主要是文件的操作,还有涉及到函数的一部分.
PS:整理博客很是费事,这就是我写的笔记,本来在线下挺好看的。拿到这里就成这熊样了,没办法。。。凑活着看吧
文件操作:
文件操作一般用open,或者用file,
格式如下:
变量名 = open('文件路径','模式','字符编码')
读取文件需要操作硬件,用户是无法直接操作硬件的,一般操作系统才有这个功能去调用硬件,所以当你告诉你
操作系统去读取a.txt 这个文件的时候,操作系统会返回一个文件的标识,这个标识就是文件句柄,你只有
拿到了这个文件的句柄你才可以去进行操作.操作完成之后一定要关闭它,不要老是占着茅坑不拉屎.别人还得用
呢.
文件操作从大的方向来说,无非就是两种: 读 写.然后这两个下面就开始分化了.
1.读
读根据需求又分:
只读: r 只能读,不能写
读写: r+ 可以读,也可以写,但是
二进制读: rb(r+b) 这个是安照二进制的格式读取.(比如读取非文本的时候,就必须用到b)
#####注意#######
1. 如果一个文件不存在,读的时候会报错
###### ####################################
读的一些操作:
f = open('a.txt','r',encoding='utf-8') #获取文件句柄
data = f.read()
f.close() #关闭文件
print(data) #大打印文件内容
读文件的几个方法:
read() : 读取文件的所有内容到内存,如果文件过大,不要这样.
readlines(): 读取文件的所有内容到内存,返回的是一个列表
readline() : 读取文件,但是不会全部读取,而是一行行 的读取.栗子如下:
f = open('a.txt','r',encoding='utf-8')
f.seek(0)
data = f.readline()
while data:
print(data.strip())
data = f.readline().strip()
f.close()
readable() : 检查文件是否可读,返回bool值.
##这个是读取一个图片的例子
import os
with open('sb.jpg','rb') as read_f,open('new_sb.jpg','wb') as write_f:
write_f.write(read_f.read())
os.remove('sb.jpg')
os.rename('new_sb.jpg','sb.jpg')
关闭文件的参数:
close() : 关闭文件
closed() : 是否关闭了文件
2.写
写根据需求又分:
只写: w 只能写,不能读
写读: w+ 可以写,也可以读
二进制写: wb(w+b) 这个是安照二进制的格式写.(比如写非文本的时候,就必须用到b)
########### 注意 #########
1. 使用write的时候,是把文件给清空,然后在写入,原有的文件内容不存在
2. 如果文件不存在,则创建
####################################
写的操作方法:
write(): 写入内容
writelines() : 写的是可以迭代的对象,他会对这个东西进行逐个的迭代.然后写入文件
writeable() : 检测是否可写
这里出现了一个新的写------追加
追加: a 这个只追加,
读写: a+ 这个可以写,可以读
二进制追加: ab(a+b) 这个是安照二进制的格式追加.(比如写非文本的时候,就必须用到b)
追加的操作方法:
和写的操作方法,一样,不过是在内容的结尾增加
文件其他的操作方法:
seek(): 光标到内容的任意地方,不过是按照字节来的.有三个数字 0 1 2
0 ---> 文章的开头
1 ---> 当前光标的位置
2 ---> 文章的结尾
seek(p,0) 移动当文件第p个字节处,绝对位置
seek(p,1) 移动到相对于当前位置之后的p个字节
seek(p,2) 移动到相对文章尾之后的p个字节
truncate(): 截断,也是按照字节来的,只保留前面的,后面的不要
flush(): 刷新到磁盘上
操作文件的另个一个方法叫 上下文管理,如果这么写了的话,就不不需要在写close()这个方法了.
with open('a.txt','r',encoding='utf-8') as f1,open('b.txt','w+',encoding='utf-8') as f2:
print(f1.readlines())
print(f2.readlines())
一个简单tail -f 功能
import time
with open('access.log','r',encoding='utf-8') as read_f:
read_f.seek(0,2)
while True:
data = read_f.read().strip()
if data:
print('新增一行数据: ',data)
time.sleep(0.5)
########################## 函数 ################################
函数使用的原因:
1. 方便管理
2. 减少了代码冗余,
3. 有结构性,可读性高
在python 函数分为两类: 一个是内置函数, 一个是自定义函数
内置函数:
这种的最常见了,字符串常见的方法就是一个个的函数
比如说list中的 max min reserve sort 等等
自定义函数:
顾名思义,自己定义的函数,至于为啥定义,还不是系统中的函数满足不了自己的需求
格式:
def 函数名():
函数体
......
函数的参数:
从大的角度来分,有两种分为实参和形参,实参一在函数调用的时候,形参在函数创建的时候
###定义阶段
def print_new(x,y,z): ##这里的x,y就是形参,形参起站位的作用,而且在调用的时候必须传值.
print(y) ## 传的值必须对应
print(y)
print(z)
###调用阶段
print_new(1,2,3) ##这里的1和2就是实参 ,有两种方法来传值,如果是明确指定的话,可以不用
print_new(y=2,x=2222,z=666)##理会参数的顺序
继续细分的话有以下几种参数:
位置参数,关键字参数,默认参数,可变长参数(*args,**kwargs),命名关键字参数
位置参数: 不在解释,上面的例子就是位置参数
关键字参数: key=value这种情况,就是在函数调用的时候输入的东西,print_new(y=2,x=1111),这种的就
就叫关键字参数
####注意事项###
1:关键字实参必须在位置实参后面
print_new(1,y=222,z=6666)
2: 不能重复对一个形参数传值
print_new(2,x=2,z=666,y=222) ###这个是错误的
默认参数: 之所以会出现这个东西,就是因为减少了重复的操作.
例子:
def new_foo (name,sex,age=18):
a='{}的性别是{},他的年龄是{}'
print(a.format(name,sex,age))
new_foo('刘康','男
如果用户不输入age,将自动使用函数里面的值,如果用户输入了值,则使用户输入的值
#####注意事项#####
1. 在定义默认参数的时候,一定要写在位置参数后面,
2. 默认参数只在定义阶段定义,且只定义一次(也就是说,
即使你在外面声明了变量,还是改变不了结果)
age=20
def new_foo (name,sex,age=18):
a='{}的性别是{},他的年龄是{}'
print(a.format(name,sex,age))
age = 16
new_foo('刘康','男') ##age的结果仍是18
3. 默认参数的值通常定义成不可变类型
可变长参数: 这个参数分为两种一个是 *args 另一个是 **kwargs
1. *args :
*会把溢出的按位置定义的实参都接收,以元组的形式赋值给args
def test_foo (x,y,*args):
print(x,y)
print(args) ###这个地方打印的其实是元组
test_foo(111,222,333,444,555)
>>> 111 222
(333,444,555)
2. **kwarges: 这个会把溢出的默认参数都接受,以字典的形式给kwargs
def test_foo2 (x,y,**kwargs):
print(x,y)
print(kwargs) ###这个地方打印的其实是个字典
test_foo2('liu','kang',name='liukang',age=18)
def foo (name,age,**kwargs):
print(name,age)
if 'sex' in kwargs:
print(kwargs['sex'])
if 'height' in kwargs:
print(kwargs['height'])
foo('liukagn',18,sex='男',height=188)
命名关键字参数:很奇葩的一个,用"*" 号分隔
def foo_name (name,age,*,sex='男性',height):
print(name,age)
print(sex,height)
foo_name('liukang',18,height=188)
# 调用的时候*号后面的参数就是命名关键字参数,这类参数必须传值,而且必须以关键字
# 实参的方式去传值
一个小例子,说了*args和**kwargs的关系,另外,如果用了*args 和**kwargs那么可以接受所有的参数
def foo(x,y,z):
print('from foo: ',x,y,z)
def foo2(*args,**kwargs):
print(args) #(1,)
print(kwargs) #{'z':2,'y':3}
foo(*args,**kwargs) #foo(*(1,),z=2,y=3)
foo2(1,z=2,y=3)
##上面的效果和下面的一样
foo(*(1,),z=2,y=3)