文件操作和函数基础
一.文件操作
在磁盘上读写文件的功能都是由操作系统提供的,现代操作系统不允许普通的程序直接操作磁盘。所以,读写文件就是请求操作系统打开一个文件对象(通常称为文件描述符),然后,通过操作系统提供的接口从这个文件对象中读取数据(读文件),或者把数据写入这个文件对象(写文件)。
1.读文件
要以读文件的模式打开一个文件对象,使用Python内置的open()函数,传入文件名和标示符。
$ cat test.txt $ This is a file
$ life is short
$ use python ------------------------ f = open("test.txt",'r') #打开test.txt文件
文件打开成功之后,开始读取文件内容,我们可以使用read()来一次性将文件内容读到内存中。
print (f.read()) >>This is a file >>life is short >>use python
调用read()会一次性读取文件的全部内容,同样的还有readlines(),一次性将文件读入内存中并逐行返回一个列表,如果读取一个大文件,这个时候内存可能就会撑不住了,因为可以通过反复调用 read(size)来达到目标,当然,你也可以将文件逐行读取到内存中。
for line in f: print(line.strip()) >>This is a file >>life is short >>use python
这种方式等同于readline(),对于大文件的处理,更加高效。但当内存足够打开一个完成的文件时,read()和readlines()则更有效率,readlines()更加适用于配置文件。
因此,我们需要根据不同的情况,选择最优的方式来进行读操作。
文件操作的最后一步则是调用close()方法来关闭文件,文件使用完毕后必须关闭,因为文件对象会占用操作系统的资源,并且操作系统同一时间能打开的文件数量也是有限的。
当然,为了避免某些时候忘记关闭文件,python提供了一个更加简介的文件打开方式——with语句。
with open ("test.txt",'r') as f: print(f.read())
2.写文件
写文件和读文件是一样的,唯一区别是调用open()
函数时,传入标识符'w'
或者'wb'
表示写文本文件或写二进制文件
with open ("test.txt",'w') as f: f.write("hello world") -------------------------------------- $ cat test.txt $ hello world
你可以反复调用write()
来写入文件,但是务必要调用f.close()
来关闭文件。当我们写文件时,操作系统往往不会立刻把数据写入磁盘,而是放到内存缓存起来,空闲的时候再慢慢写入,如果想让内容实时写入,可以使用flush()。只有调用close()
方法时,操作系统才保证把没有写入的数据全部写入磁盘。忘记调用close()
的后果是数据可能只写了一部分到磁盘,剩下的丢失了。所以,还是用with
语句来得保险。
3.文件操作标识符
r 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。
r+ 以读写方式打开文件。文件指针将会放在文件的开头。
w 以只写方式打开文件。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
w+ 以读写方式打开文件。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
a 以追加方式打开文件。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
a+ 以读写模式打开文件。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。
4.文件操作其他小tips
tell(): 打印当前位置
f = open("test",'r')
print(f.read(10))
print(f.tell())
f.close()
>>This is a
>>10
seek(offset [,from])方法改变当前文件的位置。Offset变量表示要移动的字节数。From变量指定开始移动字节的参考位置。
如果from被设为0,这意味着将文件的开头作为移动字节的参考位置。如果设为1,则使用当前的位置作为参考位置。如果它被设为2,那么该文件的末尾将作为参考位置。
f = open("test",'r') f.seek(10,0) print(f.read()) f.close()
>>file >>life is short >>use python
二.字符编码与转码
参考文章:
http://www.cnblogs.com/yuanchenqi/articles/5956943.html
三.函数基础
函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需调用其函数名即可
特性:
1.减少重复代码
2.增加可扩展性
3.方便日后维护
1.定义一个函数
def hello(): #定义一个函数名为hello的函数 print("hello world\n") hello() #调用hello()函数 >>hello world
2.函数参数
形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只在函数内部有效。函数调用结束返回主调用函数后则不能再使用该形参变量。
实参可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。因此应预先用赋值,输入等办法使参数获得确定值。
def add(x,y): #形 参 res=x+y return res count = add(a,b) #实 参 print(count)
1. 默认参数
def stu(name,age,gender="F"): res = {"name":name, "age":age, "gender":gender} return res print(stu("tom",12,"M")) #指定gender时,用指定的值 print(stu("jerry",20)) #不指定gender的时候,用默认值"F" >>{'age': 12, 'gender': 'M', 'name': 'tom'} >>{'age': 20, 'gender': 'F', 'name': 'jerry'}
由此可见,当调用函数的时候需要反复传递相同参数的时候,使用默认参数能够很好的简化函数的调用。
正常情况下,给函数传参数要按顺序,不想按顺序就可以用关键参数,只需指定参数名即可。
但记住一个要求就是,关键参数必须放在位置参数之后.
print(stu("jerry",gender="F",age=20)) >>{'gender': 'F', 'name': 'jerry', 'age': 20}
2. 非固定参数
定义一个函数的时候,不确定会传入多少参数,则可以使用非固定参数
def stu(*args,**kwargs): #*args将位置参数接受转换成元祖 , **kwargs将关键字参数转换成字典 print(args,kwargs) stu("Tom",age=12,gender="F") >>('Tom',) {'gender': 'F', 'age': 12}
3. 返回值
要想获取函数的执行结果,就可以用return语句把结果返回
注意:
函数在执行过程中,碰到return语句则会停止执行并返回结果。换言之,return语句代表函数的结束
未指定return值则函数的返回值为None
def test(x): return print("the end") print(x) test("tom") >>the end
4. 递归
在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数
递归特性:
1. 递归必须有一个明确的结束条件
2. 每次进入更深一层递归的时候,问题的规模相比上次递归应该逐步减少
3. 递归效率不高,递归层次过多会导致栈溢出,python中默认最高只能递归999次
def recu(num): if num >0: num=num-1 print(num) recu(num) recu(1000) >>999 >>... >>2 RecursionError: maximum recursion depth exceeded while calling a Python object
解决方法:
import sys sys.setrecursionlimit(1500) # set the maximum depth as 1500
5. 匿名函数
匿名函数就是不需要显式的指定函数
def map(a): print (a*a) for i in range(1,10): map(i) #匿名函数 res = map(lambda x: x * x,range(1,10)) for i in res: print (i)