目录:
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("