一、函数初始
二、函数的使用原则
三、函数的定义与调用形式
四、函数的返回值
五、函数参数的使用
一、函数初始
# 须知一:
# 硬盘空间无法修改,硬盘中的数据更新都是用新的内容覆盖旧的内容
# 内存控制可以修改
# with open('a.txt','r+t',encoding='utf-8') as f:
# f.seek(4,0)
# print(f.tell())
# f.write('我擦嘞')
# 须知二:
# 文件对应的是硬盘空间,硬盘不能修改应为文件本质也不能修改,
# 我们看到文件的内容可以修改,是如何实现的呢?
# 大的的思路:将硬盘中文件内容读入内存,然后在内存中修改完毕后再覆盖回硬盘
# 具体的实现方式分为两种:
# 1. 将文件内容发一次性全部读入内存,然后在内存中修改完毕后再覆盖写回原文件
# 优点: 在文件修改过程中同一份数据只有一份
# 缺点: 会过多地占用内存
# with open('db.txt',mode='rt',encoding='utf-8') as f:
# data=f.read()
# with open('db.txt',mode='wt',encoding='utf-8') as f:
# f.write(data.replace('kevin','SB'))
# 2. 以读的方式打开原文件,以写的方式打开一个临时文件,一行行读取原文件内容,修改完后写入临时文件...,删掉原文件,将临时文件重命名原文件名
# 优点: 不会占用过多的内存
# 缺点: 在文件修改过程中同一份数据存了两份
import os
with open('db.txt',mode='rt',encoding='utf-8') as read_f,\
open('.db.txt.swap',mode='wt',encoding='utf-8') as wrife_f:
for line in read_f:
wrife_f.write(line.replace('SB','kevin'))
os.remove('db.txt')
os.rename('.db.txt.swap','db.txt')
二、函数的使用原则
# 储备知识:
# 函数的使用应该分为两个明确的阶段
# 1. 定义阶段:只检测语法,不执行函数体代码
def func():
print('from func')
# 2. 调用阶段:会触发函数体代码的执行
# func()
#先定义后调用
# 示范一
# def foo():
# print('from foo')
# bar()
# foo()
# # 示范二:
# def bar():
# print('from bar')
#
# def foo():
# print('from foo')
# bar()
#
# foo()
# # 示范三:
# def foo():
# print('from foo')
# bar()
#
# def bar():
# print('from bar')
#
# foo()
# 示范四:
def foo():
print('from foo')
bar()
foo()
def bar():
print('from bar')
三、函数的定义与调用形式
# 一:函数的定义三种形式
'''
# 有参函数
def func(x):
pass
func(1)
# 无参函数
def bar():
pass
bar()
# 空函数
# def func():
# pass
def auth():
pass
def register():
pass
def shopping():
pass
def transfer():
pass
def pay():
pass
'''
# 二:函数调用的三种形式
# register() # 语句形式
def max2(x,y):
if x > y:
return x
else:
return y
# res=max2(10,20)*12 # 表达式
res=max2(max2(10,20),30) # 将函数的调用当作参数传给另外一个函数
print(res)
四、函数的返回值
# return 值:
# 注意点:
# 1. 函数的返回值没有类型限制
# 2. 函数的返回值没有个数限制
# 2.1 返回多个值: 多个返回值用逗号分隔开,返回的是元组形式
# def func():
# print('from func')
# return 1,1.1,'hello',[1,2,3]
#
# res=func()
# print(res,type(res))
# 2.2 返回1个值: 返回的就是该值本身
# def func():
# return 123
# res=func()
# print(res,type(res))
# 2.3 返回0个值或者干脆没有return: 返回None
# def func():
# return
# pass
# res=func()
# print(res)
# return除了有返回值的功能,还有结束函数执行的的功能
# 函数内可以有多个return,但只要执行一次,整个函数就立即结束,并且将return后的值返回
def func():
print(1)
return
print(2)
return
print(3)
func()
五、函数参数的使用
#一: 函数的参数分为两大类:
# 形式参数(形参): 在定义函数阶段,括号内定义的参数/变量名称为形参
# 实际参数(实参): 在调用函数阶段,括号内传入的值/变量值称为实参
# ps: 在调用函数阶段会将实参(值)的值绑定给形参(变量名),这种绑定关系只在调用函数时生效,在函数执行完毕后就会解除绑定
# def func(x,y): #x=1 y=2
# # x=1
# # y=2
# print(x,y)
#
# func(1,2)
#
# print(x)
# print(y)
# 二: 细分:
# 1. 位置参数:
# 1.1 位置形参: 在定义阶段,按照从左到右的顺序依次定义的形参称之为位置形参
# 特点: 但凡时按照位置定义的形参,必须被传值,多一个不行少一个也不行
# def func(x,y,z):
# print(x,y,z)
# func(1,2)
# func(1,2,3)
# func(1,2,3,4)
# 1.2 位置实参: 在调用阶段,按照从左到右的顺序依次传入的值称之为位置实参
# 特点:
# 1. 与形参一一对应
# def func(x,y,z):
# print(x,y,z)
#
# func(2,1,3)
# 2. 关键字实参: 在调用阶段,按照key=value的形式定义的实参称之为关键字实参
# 特点: 可以完全打乱顺序,但仍然能为指定的形参传值(总结:指名道姓地为指定的形参传值)
# def func(x,y,z):
# print(x,y,z)
# func(x=1,y=2,z=3)
# func(1,2,3)
# func(z=3,y=2,x=1)
# 实参的形式可以是位置实参与关键字实参混合使用,但是必须遵循原则
# 1.位置实参必须放在关键字实参的前面
# 2.不能对同一个形参重复传值
# func(1,z=3,y=2)
# func(z=3,1,y=2) #错误
# func(1,z=3,x=2,y=3) #错误
# 3. 默认形参:在定义阶段,就已经为形参赋值,该形参称之为默认参数
# 特点
# 1. 定义阶段就已经有值意味着调用阶段可以不用传值
# 2. 位置形参必须放到默认形参的前面
# 3. 默认形参的值在函数定义阶段就已经固定死了,定义阶段之后的改动不会影响该值
# 4. 默认形参的值通常应该是不可变类型
# def func(x,y,z=100):
# print(x,y,z)
# func(10,20)
# func(10,20,200)
# def register(name,age,sex='male'):
# print(name,age,sex)
#
# register('egon',18,)
# register('lxx',38,)
# register('cw',48,)
# register('yyh',58,)
# register('alex',73,'female')
# def func(x,z=100,y):
# print(x,y,z)
# m=10
# def func(x,y,z=m):
# #z=10
# print(x,y,z)
# m=100
# func(1,2)
# def add_hobby(name,x,hobbies=None):
# if hobbies is None:
# hobbies=[]
# hobbies.append(x)
# print('%s 的爱好有 %s' %(name,hobbies))
#
# add_hobby('egon','read',)
# add_hobby('wxx','eat',)
# add_hobby('alex','piao')
# 4. 可变长参数:
# 可变长实参:指的是在调用阶段,实参值个数是不固定的,
# 实参无非两种形式(位置,关键字实参),对应着形参也必须有两种解决方案来分别接收溢出位置实参或者关键字实参
# *--->溢出的位置实参
# **--->溢出的关键字实参
# def sum2(*x): #x=(1,2,3,4,5)
# res=0
# for i in x:
# res+=i
# return res
# print(sum2(1,2,3,4,5))
# 4.1 *的用法
# 在形参前加*:*会将溢出的位置实参存成元组的形式,然后赋值给*后的形参名
# def func(x,y,*z): #z=(3,4,5)
# print(x,y,z)
# func(1,2,3,4,5)
# 在实参前加*:但凡碰到实参中带*的,先将实参打散成位置实参再与形参做对应
# def func(x,y,z):
# print(x,y,z)
# func(1,2,[3,4,5])
# func(*[1,2,3,4,5]) #func(1,2,3,4,5)
# func(*[1,2,3]) #func(1,2,3)
# def func(x,y,*z):
# print(x,y,z)
# func(1111,2222,*[1,2,3,4,5]) #func(1111,2222,1,2,3,4,5)
# 4.2 **的用法
# 在形参前加**:**会将溢出的关键字实参存成字典的形式,然后赋值给**后的形参名
# def func(x,y,**z): #z={'c':3,'b':2,'a':1}
# print(x,y,z)
# func(1,y=2,a=1,b=2,c=3)
# 在实参前加**:但凡碰到实参中带**的,先将实参打散成关键字实参再与形参做对应
# def func(x,y,z):
# print(x,y,z)
# func(1,**{'y':2,'z':3}) #func(1,z=3,y=2)
# func(1,**{'a':2,'y':333,'z':3}) #func(1,a=2,y=333,z=3) # 错误
# def func(x,y,**z):
# print(x,y,z)
# func(**{'y':1,'x':2,'a':1111,'b':2222}) #func(y=1,x=2,a=1111,b=2222)
# 形参中:*args,**kwargs
# def func(x,*args):
# print(x)
# print(args)
#
# def func(x,**kwargs):
# print(x)
# print(kwargs)
# *与**的应用:
def index(name,age,sex):
print('index=====>',name,age,sex)
# 会将wrapper函数接收的参数格式原封不动地转嫁给其内部的index函数,必须要遵循的是index的参数规则
def wrapper(*args,**kwargs): #args=('egon',) kwargs={'sex':'male','age':18}
# print(args)
# print(kwargs)
index(*args,**kwargs) #index(*('egon',),**{'sex':'male','age':18}) #index('egon',sex='male',age=18)
# wrapper(1,2,3,4,5,a=1,b=2,c=3)
wrapper('egon',sex='male',age=18)