目录:
1、文件操作
2、函数
3、全局变量 局部变量 递归
4、函数式编程
5、高阶函数
一、文件操作
对文件操作流程
- 打开文件,得到文件句柄并赋值给一个变量
- 通过句柄对文件进行操作
- 关闭文件
现有文件如下:
1 我爱北京 2 天门上太阳升 3 Somehow, it seems the love I knew was always the most destructive kind 4 不知为何,我经历的爱情总是最具毁灭性的的那种 5 Yesterday when I was young 6 昨日当我年少轻狂 7 The taste of life was sweet 8 生命的滋味是甜的 9 As rain upon my tongue 10 就如舌尖上的雨露 11 I teased at life as if it were a foolish game 12 我戏弄生命 视其为愚蠢的游戏 13 14 when i was yong i am a beautiful 15 --------------diao----------
现对对文件进行各种操作:
#读文件: ''' f = open("yesterday",'r',encoding="utf-8") #相当于打开是一个内纯对象 给他赋值给一个变量,通过变量去操作内容 data = f.read() print(data) #读文件 光标已经到了最后 '''
#写文件 #f.write("我爱北京") # w 的形式是创建一个文件,如果以前有一个同名文件会被覆盖 要小心 ''' f = open("yesterday2",'w',encoding="utf-8") #打开是一个内纯对象 给他赋值给一个变量,通过变量去操作内容 #print(data) #读文件 光标已经到了最后 r 读只能读 w 写只能写 a 追加 f.write("我爱北京 ") # 换行 f.write("天门上太阳升") '''
#追加 ''' f = open("yesterday2",'a',encoding="utf-8") #a = append 追加 f.write(" when i was yong i am a beautiful ") #data = f.read() #print('------read',data) f.close() '''
#只读前5行 ''' f = open("yesterday",'r',encoding="utf-8") #print(f.readline()) for i in range(5): print(f.readline()) '''
#把文件编列一遍 ''' f = open("yesterday",'r',encoding="utf-8") #print(f.readlines()) for line in f.readlines(): print(line.strip()) #.strip()把空格和换行都去掉 '''
# 只打印10行 low loop ''' f = open("yesterday",'r',encoding="utf-8") #print(f.readlines()) #读出内容变成一个列表 for index,line in enumerate(f.readlines()): if index == 9: print("-------分割-------") continue print(line.strip()) #.strip()把空格和换行都去掉 '''
# 高级循环 ''' f = open("yesterday",'r',encoding="utf-8") for line in f: print(line.strip()) '''
#高级循环 ''' count = 0 f = open("yesterday",'r',encoding="utf-8") for line in f: if count == 9: print('--------分割-----') count += 1 continue print(line.strip()) count += 1 '''
''' f = open("yesterday",'r',encoding="utf-8") print(f.tell()) #打印出光标指针在哪儿 print(f.read(5)) #只读5个字符 print(f.readline()) print(f.readline()) print(f.readline()) print(f.tell()) #打印出光标指针在哪儿 f.seek(0) #让光标回到某个位置 0 就是回到开头 配合tell使用 print(f.readline()) #又会打印第一行 print(f.encoding) #打印文件编码 print(f.fileno()) #返回一个文件编号 这个文件在内存里的一个编号 print(f.name) #返回文件名 print(f.readable()) #判断文件是否可读 print(f.flush()) #当缓存满了把数据刷到磁盘里 '''
#读写 有些地方是可用到的 ''' f = open("yesterday2",'r+',encoding="utf-8") #文件句柄 r+ 读写 print(f.readline()) print(f.readline()) print(f.readline()) f.write("--------------diao----------") print(f.readline()) '''
#写读 基本没用 ''' f = open("yesterday3",'w+',encoding="utf-8") #文件句柄 w+ 写读 #先创建文件在写三行 f.write("--------------diao---------- ") f.write("--------------diao---------- ") f.write("--------------diao---------- ") print(f.tell()) f.seek(10) #虽然光标会回到10处,但后面再写的时候还是会在最后面追加,防止覆盖 print(f.readline()) f.write("shoud be at the begining of the second line") f.close() '''
#追加读写 #f = open("yesterday3",'a+',encoding="utf-8") #文件句柄
#二进制格式去读这个文件 ''' #f = open("yesterday3",'rb',encoding="utf-8") #文件句柄 #ValueError: binary mode doesn't take an encoding argument f = open("yesterday3",'rb') #文件句柄 二进制文件 print(f.readline()) print(f.readline()) print(f.readline()) #在1、网络传输时只能用二进制格式 (在2.x里还可以字符) #在2、当文件是二进制时 用字符模式打开有可能损坏文件 ''' f = open("yesterday3",'wb') #文件句柄 二进制文件 在3.x里一定要明确的区分二进制 和 字符串 f.write("hello binary ".encode()) f.close() #打开文件一定要记得关闭,不然占用内存 或误操作
# 文件修改 ''' f = open("yesterday2",'r',encoding='utf-8') f_new = open("yesterday2.bak","w",encoding="utf-8") for line in f: #从f 文件里循环的读,然后吧每一行又写到另一个文件里, #如果有“雨露”那就替换 if "雨露" in line: line = line.replace("雨露","gaofan") f_new.write(line) f.close() f_new.close() '''
# 通过传参数修改 ''' import sys find_str = sys.argv[1] replace_str = sys.argv[2] f = open("yesterday2",'r',encoding='utf-8') f_new = open("yesterday2.bak","w",encoding="utf-8") for line in f: #从f 文件里循环的读,然后吧每一行又写到另一个文件里, #如果有“雨露”那就替换 if find_str in line: line = line.replace(find_str,replace_str) f_new.write(line) f.close() f_new.close() '''
#with 语句 避免打开文件忘记关闭 如果不关闭造成不必要的空间浪费, ''' with open("yesterday2","r",encoding="utf-8") as f: for line in f: print(line) '''
#同时打开多个文件 with open("yesterday2","r",encoding="utf-8") as f, open("yesterday2","r",encoding="utf-8") as f2: for line in f: print(line)
二、函数
三种编程方式:
1、面向对象:类--》class定义
2、面向过程:过程--》def 定义
3、函数式编程:函数--》def 定义
# Author:land
#定义一个函数
def func1():
"""testing"""
print("in the func1")
return 0
#定义一个过程
def func2():
"""testinf2"""
print("in the func2")
#区别 两者都是可以调用的 过程只是没有返回值的函数
#调用函数
x = func1()
y = func2()
print("from func1 return is %s" %x)
print("from func1 return is %s" %y)
#函数的调用
import time
def logger_test():
time_format = '%Y-%m-%d %X'
time_current = time.strftime(time_format)
with open('a.txt','a+') as f:
f.write("time %s end action
" %time_current)
def test1():
print("in the test1")
logger_test() #前面只需定义一次logger_test()的代码
def test2():
print("in the test2")
logger_test()
def test3():
print("in the test3")
logger_test()
test1()
test2()
test3()
函数:是定义一段代码的执行过程
1、为何要用函数?
#1、代码的组织结构不清晰,可读性差
#2、遇到重复的功能只能重复编写实现代码,代码冗余
#3、功能需要扩展时,需要找出所有实现该功能的地方修改之,无法统一管理且维护难度极大
2、函数分类
#1、内置函数
为了方便我们的开发,针对一些简单的功能,python解释器已经为我们定义好了的函数即内置函数。对于内置函数,我们可以拿来就用而无需事先定义,如len(),sum(),max()
ps:我们将会在最后详细介绍常用的内置函数。
#2、自定义函数
很明显内置函数所能提供的功能是有限的,这就需要我们自己根据需求,事先定制好我们自己的函数来实现某种功能,以后,在遇到应用场景时,调用自定义的函数即可
3、如何自定义函数?
#语法
def 函数名(参数1,参数2,参数3,...):
'''注释'''
函数体
return 返回的值
#函数名要能反映其意义
函数返回值:
无return->None
return 1个值->返回1个值
return 逗号分隔多个值->元组
什么时候该有返回值?
调用函数,经过一系列的操作,最后要拿到一个明确的结果,则必须要有返回值
通常有参函数需要有返回值,输入参数,经过计算,得到一个最终的结果
什么时候不需要有返回值?
调用函数,仅仅只是执行一系列的操作,最后不需要得到什么结果,则无需有返回值
通常无参函数不需要有返回值
函数的调用形式:
1 语句形式:foo()
2 表达式形式:3*len('hello')
3 当中另外一个函数的参数:range(len('hello'))
函数的参数:
1、形式参数与实际参数
#形参即变量名,实参即变量值,函数调用时,将值绑定到变量名上,函数调用结束,解除绑定
'''
def test(x,y): # 形式参数
print(x)
print(y)
test(1,2) #1,2,是实际参数,这是在内存实际存在的
# 实参 跟 形参一一对应的 个数不能超,
test(y=1,x=2) #与形参位置无关
test(1,y=22) #位置 和 关键 参数都有时以位置参数为准
#还有关键参数不能再位置参数前面
'''
2、默认参数
'''
def test(x,y=2): #默认参数
print(x)
print(y)
test(1,3)
#默认参数特点:调用函数的时候,默认参数可有可无,
#用途:1,默认安装值 2、
'''
3、参数组
可变长参数:
可变长指的是实参值的个数不固定
而实参有按位置和按关键字两种形式定义,针对这两种形式的可变长,形参对应有两种解决方案来完整地存放它们,分别是*args,**kwargs
#参数组
#*args 接受位置参数
'''
def test(*args):
print(args)
test(1,2,3,)
test(*[1,2,3,4,5,]) # args=tuple([1,2,3,4,5])
'''
# def test(x,*args):
# print(x)
# print(args)
#
# test(1,2,3,4,5,6,7,)
#**kwargs 把n个关键字参数转换成字典的方式
# 接受关键字参数
#
# def test(**kwargs):
# print(kwargs)
#
# test(name='laiang',age=3,sex='F')
def test(name,**kwargs):
print(name)
print(kwargs)
test('laiang',age=3,sex='F')
test:
1写函数,用户传入修改的文件名,与要修改的内容,执行函数,完成批量修改操作
# -*- coding:utf-8 -*- #在python2.x上执行时声明utf-8 # Author:land import os def modify_file(filename,old,new): with open(filename,'r') as read_f, open('.bak_file','w') as write_f: for line in read_f: if old in line: line = line.replace(old,new) write_f.write(line) os.remove(filename) os.rename('.bak_file',filename) modify_file('/root/python_test/a.txt','雨露','露水')
下面是在python3上执行:
# Author:land def modify_file(filename,old,new): import os with open(filename,'r',encoding='utf-8') as read_f, open('.bak_file','w',encoding='utf-8') as write_f: for line in read_f: if old in line: line = line.replace(old,new) write_f.write(line) os.remove(filename) os.rename('.bak_file',filename) modify_file('a.txt','雨露','露水')
2、写函数,计算传入字符串中【数字】、【字母】、【空格] 以及 【其他】的个数
def check_str(msg): res = { #定义一个字典 'num':0, 'string':0, 'space':0, 'other':0, } for i in msg: #把传入的字符串进行遍历,然后判断 写入字典 if i.isdigit(): res['num'] += 1 elif i.isalpha(): res['string'] += 1 elif i.isspace(): res['space'] += 1 else: res['other'] += 1 return res res = check_str('hello,my name is tiger 666') print(res)
3、 写函数,检查传入列表的长度,如果大于2,那么仅保留前两个长度的内容,并将新内容返回给调用者
def func1(seq): if len(seq) > 4: seq = seq[0:4] return seq print(func1([1,2,3,4,5,6,7,]))
4、写函数,检查获取传入列表或元组对象的所有奇数位索引对应的元素,并将其作为新列表返回给调用者。
def func2(seq): return seq[::2] print(func2([4,43,2,54,3,1,66,]))
5、写函数,检查字典的每一个value的长度,如果大于2,那么仅保留前两个长度的内容,并将新内容返回给调用者。
def check_dic(dic): d = {} for k,v in dic: if len(v) > 2: d[k] = v[0:2] return d print(check_dic({'k1':'ab','k2':'12','k3':'ert'}))
三、全局变量 局部变量 递归
在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数
#递归 def cale(n): print(n) if int(n/2) > 0: return cale(int(n/2)) print("--->>",n) cale(10)
递归特性:
1. 必须有一个明确的结束条件
2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少
3. 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)
总结:1、明确的结束条件
2、问题规模逐渐减少
3、效率不高
递归应用二分查找:
1 data = [1, 3, 6, 7, 9, 12, 14, 16, 17, 18, 20, 21, 22, 23, 30, 32, 33, 35] 2 3 def binary_search(dataset, find_num): 4 print(dataset) 5 6 if len(dataset) > 1: 7 mid = int(len(dataset) / 2) 8 if dataset[mid] == find_num: # find it 9 print("找到数字", dataset[mid]) 10 elif dataset[mid] > find_num: # 找的数在mid左面 11 print("